pan*_*ajt 6 java multithreading
Q1.什么是Java中的condVar?如果我看到下面的代码,条件变量是否必须在' mutex.acquire() '和' mutex.release() '块中?
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我有三个线程myThreadA,myThreadB,myThreadC运行,调用相同的函数commonActivity(),触发函数myWorkReport(),例如
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();
}
}
Run Code Online (Sandbox Code Playgroud)
Q2.使用timedwait是一个很好的做法.我可以通过使用sleep()实现相同的目标.如果使用sleep()调用不好,为什么?
Q3.有没有更好的方法来做上述事情?
Q4.是否必须有condition.signal()为每condition.timedwait(时间);
Q1)最好的资源可能是Condition类的JavaDoc.条件变量是一种机制,允许您在允许方法继续之前测试特定条件是否成立.在您的示例中,有两个条件,notFull和notEmpty.
示例中显示的put方法在notFull尝试将元素添加到数组之前等待条件变为true,并且一旦插入完成,它就会发出notEmpty条件以唤醒任何被阻塞的线程,等待从数组中删除元素.
...条件变量是否必须在'mutex.acquire()'和'mutex.release()'块中?
任何更改条件变量的调用都需要在同步区域内 - 这可以通过内置synchronized关键字或java.util.concurrent包提供的其中一个同步器类(如Lock)来实现.如果您没有同步条件变量,则有两种可能的负面结果:
丢失信号 - 这是一个线程检查条件并发现它不成立的地方,但在它阻塞另一个线程进入之前,执行一些操作以使条件变为真,然后发出信号等待条件的所有线程.不幸的是,第一个线程已经检查了条件,并且无论如何都会阻塞,即使它实际上可以继续.
第二个问题是通常的问题,您可以让多个线程同时尝试修改共享状态.在您的示例的情况下,多个线程可以put()同时调用,然后所有线程都检查条件并看到数组未满并尝试插入其中,从而覆盖数组中的元素.
Q2)定时等待对于调试目的非常有用,因为它们允许您在线程未通过信号唤醒的情况下记录信息.
使用sleep()代替定时等待不是一个好主意,因为如上所述,您需要await() 在同步区域内调用该方法,并且sleep()不会释放任何保持锁定await().这意味着任何休眠线程仍将保持它们已获取的锁定,从而导致其他线程不必要地阻塞.
Q4)从技术上讲,signal()如果您正在使用定时等待,则不需要调用,但这样做意味着所有等待都不会在超时结束后返回,这至少是低效率的.
| 归档时间: |
|
| 查看次数: |
33482 次 |
| 最近记录: |