很明显,Sun 实现的方法并不简单地让时间给指定线程,实际上它首先尝试获取线程对象上的监视器。
它不会屈服于加入的线程,它只是在假设线程将在某个时刻运行到完成的情况下等待。在线程上使用 join() 不会使其比任何其他准备运行的线程更有可能运行。
- 如果 N 个线程都尝试加入同一个线程,并且它们都指定了相同的超时 T,那么其中一个线程最终将等待至少 N*T 毫秒。换句话说,每个线程都必须“等待轮到它”来执行它的等待。单独的线程串行而不是并行执行连接是否合理?
线程被设计为同时工作。如果他们都在等待,他们会同时这样做。一个等待的线程不会让另一个线程等待更长的时间。
.2。进入具有非零超时的连接的线程可能永远不会返回。
除非您打算这样做,否则不会。
这是因为无法保证监视器永远可用。
您建议的情况只有在线程获得线程上的锁然后永远持有它而无需等待时才会发生。这是一个编程错误。恕我直言,您永远不应该直接获得线程对象的锁。
如果线程在阻塞 I/O 操作之前获得了自己的监视器,并且该操作挂起,那么任何尝试加入该线程的线程也将挂起。
Java 不能保护您免受自己 JVM 中的恶意代码的侵害。
明确超时的操作无限期挂起是否合理?
如果它被无限期锁定,是的。
.3。为了编写使用该方法的正确程序,调用者必须事先知道目标线程或其他线程是否可以持有监视器。
永远不要锁定线程对象,你没有理由需要这样做,你也不会有这个问题。如果您想开始研究可能使其他开发人员或您自己感到困惑的所有方式,那么 Threads 不是您开始恕我直言的地方。
例如,假设线程 1 正在执行某种处理工作,然后线程 2 以 0 的超时时间加入线程 1,然后线程 3 尝试以 10 毫秒的超时时间加入线程 1,会发生什么情况。 0 超时连接意味着线程 2 将一直等到线程 1 退出。但是线程 3 不能开始等待,直到线程 2 释放监视器,
线程 2 在调用 wait 后立即释放监视器。它不能同时等待和保持显示器。
因此,线程 3 的 10 毫秒等待有效地被静默转换为无限期等待,这不是调用者的意图。
没有。查看以前的 cmets。
不要求调用者知道实现细节是否违反了封装原则?
会的。
.4。如果线程因为无法获取监视器而被阻塞,则它是不可中断的,并且不会按照文档中的描述抛出 InterruptedException。因此,一个线程不仅可能等待比预期更长的时间,甚至无限期地等待,它可能变得完全没有响应,导致整个程序挂起。可中断操作变得无响应是否合理?
是的。但这是一种非常罕见的情况。如果你使用写的代码,你所指的情况最多只会存在几毫秒。
总的来说,让超时的操作依赖于获取监视器似乎是不合适的,除非可以保证获取监视器的任务本身会超时。线程连接坏了吗?
您可以使用更新的 Java 5 并发库执行您的建议。
但是,我建议您不要假设超时可以保证精确到毫秒。此方法使用的 currentTimeMillis() 在 Windows XP 上仅精确到大约 16 毫秒,等待/睡眠通常比在 Linux 上的小超时时间长 2 毫秒。
恕我直言,如果您需要超过 40 毫秒的精度,您可能会遇到困难,但是如果您解决这个问题,您会发现这不是问题。