我正在构建一个系统,其中调用线程的进度取决于两个变量的状态。一个变量由外部源(与客户端线程分开)偶尔更新,并且多个客户端线程根据两个变量的情况而阻塞。系统是这样的
TypeB waitForB() { // Can be called by many threads.
synchronized (B) {
while (A <= B) { B.wait(); }
A = B;
return B;
{
}
void updateB(TypeB newB) { // Called by one thread.
synchronized (B) {
B.update(newB);
B.notifyAll(); // All blocked threads must receive new B.
}
}
我需要所有被阻止的线程在 B 更新后接收新值。但问题是,一旦单个线程完成并更新 A,等待条件再次变为 true,因此其他一些线程会被阻塞并且无法接收 B 的新值。有没有一种方法可以确保只有最后一个线程在 B 更新 A 上被阻止,或者获得此行为的其他方式?
最佳答案
我有以下想法:为了保持等待 B 的“好”值的线程计数器,首先唤醒的线程将缓存该好值,并让其他读者在那一刻读取它。我们让新的读者脱离等待循环,直到所有先前的回合线程完成。
以下是代码概要:
final AtomicInteger A = new AtomicInteger(-1), B = new AtomicInteger(-1);
int cachedB = -1;
int readersCount;
int waitForB() throws InterruptedException { // Can be called by many threads.
synchronized (B) {
while (cachedB != -1) B.wait();
readersCount ++;
while (A.get() <= B.get()) { B.wait(); }
if (cachedB == -1) {
cachedB = B.get();
A.set(B.get());
readersCount--;
if (readersCount == 0) { cachedB = -1; B.notifyAll(); }
return B.get();
} else {
int ret = cachedB;
readersCount--;
if (readersCount == 0) { cachedB = -1; B.notifyAll(); }
return ret;
}
}
}
void updateB(int newB) { // Called by one thread.
synchronized (B) {
B.set(newB);
B.notifyAll(); // All blocked threads must receive new B.
}
}
关于java - 确保所有等待线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19867311/