java 条件变量,什么是java中的条件变量?

Q1. What is a condVar in Java? If I see the code below, does a condition variable necessarily have to be within the 'mutex.acquire()' and 'mutex.release()' block?

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();

}

}

I have three threads myThreadA, myThreadB, myThreadC running which call the same function commonActivity() which triggers the function myWorkReport() e.g.

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();

}

}

Q2. Is using timedwait a good practice. I could have achieved the same by using sleep(). If using sleep() call is bad, Why?

Q3. Is there any better way to do the above stuff?

Q4. Is it mandatory to have condition.signal() for every condition.timedwait(time);

解决方案

Q1) The best resource for this is probably the JavaDoc for the Condition class. Condition variables are a mechanism that allow you to test that a particular condition holds true before allowing your method to proceed. In the case of your example there are two conditions, notFull and notEmpty.

The put method shown in your example waits for the notFull condition to become true before it attempts to add an element into the array, and once the insertion completes it signals the notEmpty condition to wake up any threads blocked waiting to remove an element from the array.

...does a condition variable necessarily

have to be within the

'mutex.acquire()' and

'mutex.release()' block?

Any calls to change the condition variables do need to be within a synchronized region - this can be through the built in synchronized keyword or one of the synchronizer classes provided by the java.util.concurrent package such as Lock. If you did not synchronize the condition variables there are two possible negative outcomes:

A missed signal - this is where one thread checks a condition and finds it does not hold, but before it blocks another thread comes in, performs some action to cause the condition to become true, and then signals all threads waiting on the condition. Unfortunately the first thread has already checked the condition and will block anyway even though it could actually proceed.

The second issue is the usual problem where you can have multiple threads attempting to modify the shared state simultaneously. In the case of your example multiple threads may call put() simultaneously, all of them then check the condition and see that the array is not full and attempt to insert into it, thereby overwriting elements in the array.

Q2) Timed waits can be useful for debugging purposes as they allow you to log information in the event the thread is not woken up via a signal.

Using sleep() in place of a timed wait is NOT a good idea, because as mentioned above you need to call the await() method within a synchronized region, and sleep() does not release any held locks, while await() does. This means that any sleeping thread will still hold the lock(s) they have acquired, causing other threads to block unnecessarily.

Q4) Technically, no you don't need to call signal() if you're using a timed wait, however, doing so means that all waits will not return until the timeout has elapsed, which is inefficient to say the least.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值