线程是否有可能在 wait() 循环中饿死?
Is it possible for a thread to starve at wait() loop?
假设我有这个方法
/*1*/ public synchronized void method1() throws InterruptedException {
while (condition)
/*2*/ wait();
/*3*/ notify();
}
假设,我们在第 2 行有一个 Thread 1
等待条件,因此线程 1 将处于状态 WAITING
.
现在Thread 2
进入,不满足条件,所以绕过while循环然后Thread 2
在第3行调用notify
,然后Thread 1
应将其状态从 WAITING
更改为 BLOCKED
,直到 Thread 2
完全退出。
假设现在,在Thread 2完全退出之前,Thread 3
在synchronized块外BLOCKED
获取monitor
有没有可能 Thread 3
在 Thread 1
之前获得锁? Thread 4
、Thread 5
等可以一样吗?在那种情况下,Thread-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();
}
}
记住,公平锁是有代价的,你应该有真正的理由去使用它
来自 JavaDoc https://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.
假设我有这个方法
/*1*/ public synchronized void method1() throws InterruptedException {
while (condition)
/*2*/ wait();
/*3*/ notify();
}
假设,我们在第 2 行有一个 Thread 1
等待条件,因此线程 1 将处于状态 WAITING
.
现在Thread 2
进入,不满足条件,所以绕过while循环然后Thread 2
在第3行调用notify
,然后Thread 1
应将其状态从 WAITING
更改为 BLOCKED
,直到 Thread 2
完全退出。
假设现在,在Thread 2完全退出之前,Thread 3
在synchronized块外BLOCKED
获取monitor
有没有可能 Thread 3
在 Thread 1
之前获得锁? Thread 4
、Thread 5
等可以一样吗?在那种情况下,Thread-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();
}
}
记住,公平锁是有代价的,你应该有真正的理由去使用它
来自 JavaDoc https://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.