据我所知,线程上的yield()不释放该线程的锁。因此,如果有两个线程,并且它们都在线程池中具有同步块,则优先级较低的A和优先级较高的B。如果线程A正在运行并且在A中调用yield(),则线程B现在将由调度程序运行。因为目前,线程A仍然持有锁,所以线程B不能进入关键块?从我的理解,这将导致僵局?
请让我知道我错过了什么吗?
非常感谢:)
答案 0 :(得分:3)
这里有一些混乱。
没有死锁,因为只有一个锁。你需要至少两个锁来解决僵局。
yield()
基本上什么也没做。见Javadoc。
在任何时候,可能包括当您调用yield()
时,优先级较高的线程将阻止尝试获取锁定。因此它不再有资格执行。因此,调度程序必须安排其他可运行的东西。
同时优先级较低的线程仍然可以运行(即有资格执行),所以它迟早会被调度,所以它会继续执行。迟早它会释放它的锁,这将允许更高优先级的线程获取它并继续执行它。
答案 1 :(得分:2)
产量不会死锁,因为它只是调度程序的瞬态建议,而不是永久状态,如EJP的答案中更好地解释的那样。
如果您的目标是在关键部分中屈服于更高优先级的线程,那么您无法通过yield()
完成所需的任务,因为它不会与锁相互作用(即,它不知道或关心当前线程持有锁。)
但是,您可以使用Object.wait()
等方法,它可以释放当前持有的锁。但它具有特定的使用模式(即,您wait()
以便稍后通知) - 这可能不符合您的需求。如果不是,Java 8提供了丰富的同步原语(与每个Object
关联的隐式监视器分开) - 其中一个可能符合您的需求。
答案 2 :(得分:1)
具有较高调度优先级的实时线程存在这一事实不会阻止优先级较低的线程运行。线程必须存在,并且必须是实时的,并且必须是 runnable 。
阻塞等待互斥锁的线程无法运行。正在等待条件变量的线程不可运行。等待CPU运行以外的任何其他线程都不可运行。
只要存在较高优先级线程不需要的CPU,就允许低优先级线程运行。如果他们不是,那么" priority"没有意义。
话虽如此,除非你是在一个特殊的"实时" Java的实现,"优先级"您为线程设置的不是他们真正的调度优先级:它们只是调度程序的提示,如果需要,应允许一个线程使用比另一个更多的CPU时间。