有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

假设我有这个方法

/*1*/    public synchronized void method1() throws InterruptedException {
    
            while (condition)
 /*2*/           wait();


  /*3*/      notify();
      }

假设在第二行等待条件中有一个Thread 1,那么线程1将处于状态WAITING

现在Thread 2进入,它不满足条件,因此它绕过while循环,然后Thread 2在第3行调用notify,然后Thread 1应该将其状态从WAITING更改为BLOCKED,直到Thread 2完全退出

现在假设,在线程2完全退出之前,Thread 3在同步块之外BLOCKED以获取监视器

是否可能Thread 3Thread 1之前获取锁?对于Thread 4Thread 5等等,情况是否相同?在这种情况下,Thread-1将处于饥饿状态

这在概念上是可能的吗

编辑:如果是这样,我如何防止饥饿


共 (1) 个答案

  1. # 1 楼答案

    How do I prevent starvation if this is the case?

    不能使用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

    The constructor for this class accepts an optional fairness parameter. When set true, under contention, locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order. Programs using fair locks accessed by many threads may display lower overall throughput (i.e., are slower; often much slower) than those using the default setting, but have smaller variances in times to obtain locks and guarantee lack of starvation. Note however, that fairness of locks does not guarantee fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain it multiple times in succession while other active threads are not progressing and not currently holding the lock. Also note that the untimed tryLock method does not honor the fairness setting. It will succeed if the lock is available even if other threads are waiting.