What is a state variable in java?

Q1. What is condVar in Java? If I see the code below, is it necessary for the condition variable to be in the mutex.acquire () and mutex.release () blocks ?

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 , which call the same commonActivity () function, which runs the myWorkReport () function, for example

 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 achieve the same using sleep (). If the sleep () call is bad, why?

Q3. Is there a better way to do these things?

Q4. It is mandatory to have a .signal () condition for each condition.timedwait (time);

+7
java multithreading design
source share
5 answers

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

The put method shown in your example expects the notFull condition notFull become true before it tries to add an element to the array, and as soon as the insert is completed, it signals the status of notEmpty to wake up any threads blocked waiting to remove the element from the array .

... has a mandatory variable conditions must be within the 'mutex.acquire ()' and 'mutex.release ()' block?

Any calls to change the condition variables must be within the synchronous area - this can be through the built-in synchronized or one of the synchronizer classes provided by the java.util.concurrent package, for example Lock . If you did not synchronize the condition variables, there are two possible negative results:

  • Missed signal - here one thread checks the status and finds that it is not held, but before it blocks another thread, it performs some actions to force the condition to become true, and then signals all threads to wait on the condition. Unfortunately, the first thread has already checked the condition and will still block it, even if it can actually continue.

  • The second problem is a common problem in which multiple threads can simultaneously change the sharing state. In the case of your example, several threads can call put() at the same time, all of them then check the condition and see that the array is not full and tries to insert into it, thereby overwriting the elements in the array.

Q2) Time-outs can be useful for debugging purposes, since they allow you to record information if the stream has not woken up through the signal.

Using sleep() instead of timeout is NOT a good idea because, as mentioned above, you need to call the await() method within the synchronized area, and sleep() does not release the locked locks, but await() does. This means that any sleeping thread still holds the lock (s) they acquired, causing other threads to block unnecessarily.

Q4) Technically, you do not need to call signal() if you are using a timeout, however this means that all expectations will not be returned until the timeout expires, which is at least inefficient.

+6
source share

1: The Condition object is linked (and retrieved from) by the Lock object (aka mutext). The javadoc for the class is clear enough about its use and application. To wait on the condition that you need to get a lock, and it is good coding practice to do this in a try / finally block (like yours). As soon as a thread that has acquired a lock waits for a condition for this lock, the lock will be rejected (atomically).

2: The use of latency is necessary to ensure the viability of your program when the condition that you expect never occurs. Its definitely a more complex form, and it is completely useless if you do not check the fact that you have run out of time and take steps to handle the timeout condition.

Using sleep is an acceptable form of waiting for something, but if you are already using a lock ("mutex") and have a condition variable for this lock, it does not make sense to not use the method to wait for a condition to time :

For example, in your code you simply wait for a given period, but DO NOT check if a condition has occurred or if you have run out of time. (This is a mistake.) What you should do is check if your timed call returned true or false. (If it returns false, then it expires, and the condition has NOT occurred (yet)).

 public void myThreadA(){ mutexA.acquire(); try{ while(runningA){ //runningA is a boolean variable if(conditionA.await (sleepATimeoutNanos)) commonActivity(); else { // timeout! anything sensible to do in that case? Put it here ... } } } finally{ mutexA.release(); } } 

Q3: [edited] For snippets of code, a more detailed context is required to be clear. For example, it is not entirely clear if the conditions in the threads are all the same (but I assume that they are).

If all you are trying to do is ensure that commonActivity () only runs one thread at a time, and some sections of commonActivity () DO NOT require conflict management, and you require a timeout tool on your expectations, you you can just use semaphore . Note that sempahore has its own set of methods for timed waiting .

If ALL of commonActivity () is critical, and you really don't mind waiting (no timeouts), just make commonActivity () a synchronized method.

[final edit :)] To be more formal about this, conditions are commonly used in scenarios where you have two or more threads interacting with a task and you need manual shutdowns between threads.

For example, you have a server that processes asynchronous responses to user requests, and the user waits for the Future object to complete. In this case, the condition is perfect. A future implementation expects a condition, and the server signals its completion.

In the old days, we will use wait () and notify (), but this was not a very reliable (or trivially safe) mechanism. Lock and Condition objects were designed specifically to address these shortcomings.

(A good online resource as a starting point )

Buy and read this book .

+3
source share

Q1 . I believe in a โ€œcondition variableโ€, you refer to what you check to determine the condition in which you waited. For example, if you have a typical situation with a producer-consumer, you can implement it somehow like:

 List<T> list; public T get() { synchronized (list) { if (list.get(0) == null) { list.wait(); } return list.get(0); } } public void put(T obj) { synchronized (list) { list.add(obj); list.notify(); } } 

However, due to the possibility of false awakening of threads, the consumer method may exit the wait() call while the list is still empty. Thus, it is good practice to use a condition variable for waiting / sleeping / etc. until the condition is true:

 while (list.get(0) == null) { list.wait(); } 

using while instead of if means that the consumer method will use the consumer method only to exit this block if it should definitely return something. Generally speaking, any call to sleep or wait or lock caused by a condition, and where you expect a change in the condition, should be in the while block, which checks this condition for each cycle.

In your situation, you already do this with a while (count == array.length) notFull.await() around notFull.await() .

Q2 . Temporary waiting is usually a good practice - a timeout allows you to periodically check the health of your environment (for example, the flag flag is disabled), while non-urgent waiting can only be stopped by interruption. On the other hand, if the wait will continue to block in any case until the condition is true, it does not matter much, it wakes up every 50 ms (say) until notify() happens after 2 seconds or if it just blocks continuously in these 2 seconds.

As for wait () vs sleep (), the first rule is preferable, since this means that you wake up as soon as you can take action. Thread.sleep(500) means that this thread definitely does nothing for the next 500 ms, even if the expected thing is ready 2 months later. obj.wait(500) , on the other hand, would wake up 2 ms in a dream and continue processing. Since sleep introduces unconditional delays in your program, they are usually a clunkier way to do something - they only work when you do not expect any specific conditions, but actually want to sleep for a certain amount of time (for example, a thread cleaning that fires every 60 seconds). If you are sleeping because you expect some other thread to do something in the first place, use wait() (or another synchronous method like CountDownLatch ) CountDownLatch .

Q3 . Pass - it looks like there are a lot of templates, and since there are no comments in the code, and you did not explain what it should do and how it should behave, I am not going to try to change the engineer, which of what you wrote .; -)

0
source share

Q1. State variables are part of object monitoring , which is sometimes used to synchronize threads. I do not understand these specific implementations, but usually the use of conditional variables should be done in the critical section, so mutex.acquire and release are required.

Q2. timedwait waits for a signal subject to an OR variable timeout, and then requests a critical section. Therefore, it is different from sleep.

Q3. I am not sure, but I think that you can use the built-in monitor functions in java: synchronized for mutual exclusion and wait and notify instead of cond vars. This way you reduce the dependencies of your code.

0
source share

Q1. I think the documentation gives a good description. And yes, before await or signal you must hold the lock associated with the condition.
Q2. timedWait not in the Condition API, it is in the TimeUnit API. If you use Condition and want to have a timeout to wait, use await(long time, TimeUnit unit) . And having a timeout is usually a good idea - no one wants the program to freeze forever - if you know what to do if a timeout occurs.
Sleep is waiting unconditionally and waiting for the event. They have different goals. Q3. I do not know what this code should do. If you want to perform an action cyclically, with some break between each iteration, use sleep instead of conditions.
Q4. As I wrote above, conditions do not have a timedWait method, they have an await method. And calling await means you want to wait for an event to occur. This suggests that sometimes this event occurs, and someone signals about it. Correctly?

0
source share

All Articles