java—线程是否可能在wait()循环中饿死?

px9o7tmv  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(267)

假设我有这个方法

/*1*/    public synchronized void method1() throws InterruptedException {

            while (condition)
 /*2*/           wait();

  /*3*/      notify();
      }

假设我们有一个 Thread 1 在第二行等待条件下,线程1将处于状态 WAITING .
现在 Thread 2 进入时,它不满足条件,因此它绕过while循环,然后 Thread 2 电话 notify 那么在第三行 Thread 1 应该从 WAITINGBLOCKED ,直至 Thread 2 完全退出。
假设现在,在线程2完全退出之前, Thread 3BLOCKED 在同步块之外获取监视器。
有没有可能 Thread 3 在之前获取锁 Thread 1 ? 这对我来说是一样的吗 Thread 4 ,及 Thread 5 等等那么,, Thread-1 会处于饥饿状态。
这在概念上是可能的吗?
编辑:如果是这样,我如何防止饥饿?

huwehgph

huwehgph1#

如果是这样,我如何防止饥饿?
你不能阻止它使用 synchronized 关键词。但是,您可以使用 ReentrantLock 而是因为它允许“公平”锁定

private final ReentrantLock lock = new ReentrantLock(true); // fair lock
private final Condition sync = lock.newCondition();

public void method1() throws InterruptedException {
   lock.lock();
   try {
     while (condition)
       sync.await();
     sync.signal(); 
   } finally {
     lock.unlock();
   }
}

请记住,公平锁定是有代价的,您应该有真正的理由使用它
来自javadochttps://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/reentrantlock.html
此类的构造函数接受可选的公平性参数。当设置为true时,在争用下,锁有利于向等待时间最长的线程授予访问权限。否则,此锁不保证任何特定的访问顺序。使用多线程访问的公平锁的程序可能显示较低的总体吞吐量(即较慢;通常比使用默认设置的要慢得多),但在获得锁和保证无饥饿方面的时间差异较小。但是请注意,锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的多个线程中的一个线程可能会连续多次获得公平锁,而其他活动线程则没有进行,并且当前没有持有该锁。还要注意,untimed trylock方法不支持公平性设置。如果锁可用,即使其他线程正在等待,它也会成功。

相关问题