如果线程没有失去任何监视器的所有权,它是不是会导致其他正在运行的线程被阻塞
Posted
技术标签:
【中文标题】如果线程没有失去任何监视器的所有权,它是不是会导致其他正在运行的线程被阻塞【英文标题】:if thread does not lose ownership of any monitors, could it lead other running thread blocked如果线程没有失去任何监视器的所有权,它是否会导致其他正在运行的线程被阻塞 【发布时间】:2022-01-24 04:16:10 【问题描述】:在Thread.sleep()
JavaDoc 中声明:
使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。该线程不会失去任何监视器的所有权。
我的问题是:如果线程 A 持有一个监视器并进入睡眠状态,那么线程调度程序将选择另一个可运行的线程 B 并运行它。但是如果线程 B 需要那个监视器,那么它将被阻塞,并且依赖于监视器的任何其他线程都将被阻塞,直到线程 A 从睡眠中恢复并开始运行并释放该监视器,是不是非常低效
【问题讨论】:
是的,它可以阻塞其他线程。是的,它可能效率低下。它可能比“低效”更糟糕。你不应该在拿着显示器的时候打电话给Thread.sleep()
。 (实际上,您应该可能完全避免使用sleep()
。通常有更好的选择。)
【参考方案1】:
是的。
您还期待什么其他答案?
如果你拿着显示器,显然不要睡觉。而是使用等待和通知。
当您使用等待时会发生以下情况,如果您想使用它,您会调用一个您拥有的对象来保持监视器:
synchronized (foo)
do stuff()
foo.wait();
do more stuff();
当调用wait() 时,首先,线程释放 监视器。接下来,它只会转动拇指,等待某人,任何人,在同一引用 (foo.notify()
) 上调用 notify()
。此时,wait()
方法被释放,但仍会等待,因为它现在需要重新获取该监视器才能继续。这不一定会立即发生,因为除非您拿着显示器,否则无法调用 notify()
。
这很好地解决了您的问题:您可以在释放一个监视器的同时让线程处于休眠状态(但它不会释放其他监视器)。
不过,更一般地说,使用这些低级 API 几乎从来都不是正确的做法。有一些抽象,主要是在java.util.concurrent
包中,它们要好得多。您应该打开 javadoc 并仔细阅读。
【讨论】:
以上是关于如果线程没有失去任何监视器的所有权,它是不是会导致其他正在运行的线程被阻塞的主要内容,如果未能解决你的问题,请参考以下文章