什么是Java中的条件变量?
Java中的condVar是什么?如果我看到下面的代码,条件变量是否一定必须在“ ”和“
”块内?
public void put(Object x) throws InterruptedException { mutex.acquire();
try {
while (count == array.length)
notFull.await();
array[putPtr] = x;
putPtr = (putPtr + 1) % array.length;
++count;
notEmpty.signal();
}
finally {
mutex.release();
}
}
我有三个正在运行的线程 , 和 ,它们调用相同的函数
来触发函数 例如
public void myWorkReport(){ mutexMyWork.acquire();
try{
while(runMyWork){
doWork();
conditionMyWork.timedwait(sleepMyWork);
}
}
finally{
mutexMyWork.release()
}
}
public void commonActivity(){
try{
conditionMyWork.signal();
}finally{
//cleanup
}
}
public void myThreadA(){
mutexA.acquire();
try{
while(runningA){ //runningA is a boolean variable, this is always true as long as application is running
conditionA.timedwait(sleepA);
commonActivity();
}
}
finally{
mutexA.release();
}
}
public void myThreadB(){
mutexB.acquire();
try{
while(runningB){ //runningB is a boolean variable, this is always true as long as application is running
conditionB.timedwait(sleepB);
commonActivity();
}
}
finally{
mutexB.release();
}
}
public void myThreadC(){
mutexC.acquire();
try{
while(runningC){ //runningC is a boolean variable, this is always true as long as application is running.
conditionC.timedwait(sleepC);
commonActivity();
}
}
finally{
mutexC.release();
}
}
使用timedwait是一个好习惯。我可以通过使用sleep()实现相同的目的。如果使用sleep()调用不好,为什么?
有没有更好的方法来做上述事情?
每个 是否必须具有
回答:
最好的资源可能是Condition类的JavaDoc。条件变量是一种机制,允许您在允许方法继续执行之前测试特定条件是否成立。在您的示例中,有两个条件,notFull
和notEmpty
。
您的示例中显示的put方法在notFull
条件尝试添加到数组中之前等待条件变为真,一旦插入完成,它将发出信号notEmpty
通知条件唤醒所有阻塞的线程,等待线程从数组中删除元素。
…条件变量是否一定必须在’mutex.acquire()和’mutex.release()’块内?
任何更改条件变量的调用都必须在同步区域内-
这可以通过内置synchronized
关键字或java.util.concurrent
包提供的同步器类之一(例如Lock)进行。如果您不同步条件变量,则可能有两个负面结果:
丢失信号-这是一个线程检查条件并发现它不成立的地方,但是在阻止另一个线程进入之前,它执行了一些操作以使条件变为真,然后向所有等待该条件的线程发出信号。不幸的是,第一个线程已经检查了条件,并且即使实际上可以继续执行,也仍然会阻塞。
第二个问题是通常的问题,您可能有多个线程试图同时修改共享状态。在您的示例中,可能
put()
同时调用了多个线程,然后所有线程都检查条件,并发现数组未满并尝试插入其中,从而覆盖了数组中的元素。
定时等待对于调试目的很有用,因为它们允许您在未通过信号唤醒线程的情况下记录信息。
使用sleep()
代替定时的等待是不是一个好主意,因为上面提到你需要调用await()
一个同步的区域内的方法,并sleep()
不会释放任何持有的锁,而await()
做。这意味着任何睡眠线程仍将保持其已获取的锁,从而导致其他线程不必要地阻塞。
从技术上讲,signal()
如果您使用的是定时等待,则不需要呼叫,但是,这样做意味着直到超时过去,所有等待都不会返回,这至少可以说是无效的。
以上是 什么是Java中的条件变量? 的全部内容, 来源链接: utcz.com/qa/419473.html