How to wake up all threads waiting on same condition? - java

I have a following scenario. Several threads are waiting on the same condition. And when are notified, all should stop waiting, change flag and return object:
public Object getObject(){
lock.lock();
try {
while (check)){
condition.await();
}
return returnObjectAndSetCheckToFalse();
} finally {
lock.unlock();
}
}
however this code does not work, since faster thread could change check flag to false, and second slower thread will block again.
It is possible to have a logic that both waiting threads will be awaken, they both will set check flag to false, and return object?
Or maybe it is contradictory?
The easiest way would be to change wait to if statement, however this would be vulnerable to spurious wakeup.

You could use CountDownLatch or a CyclicBarrier.
Using a Future is also a possibility, a FutureTask to be more specific. It has a conveniance method get() which can be used to block code execution until the Future has completed its job, thus fulfilling your requirements.
You could also implement your own Barrier which would do wait() in a loop until a certain condition has been met. Fulfilling that condition would trigger notifyAll(), loop would finish and all threads could continue. But that would be reinventing the wheel.

As I understand you need to return from the method body in all threads if your condition.await() returns.
This ugly solution should help although I think there's a better way to solve this:
public Object getObject() {
lock.lock();
try {
int localstate = this.state;
while (check && localstate == this.state)) {
condition.await(); // all threads that are waiting here have the same state
}
if (!check) {
this.state++; // first thread will change state thus making other threads ignore the 'check' value
}
return returnObjectAndSetCheckToFalse();
} finally {
lock.unlock();
}
}

What I think is you're trying to achieve, done using Futures:
ExecutorService executor = Executors.newCachedThreadPool();
// producer
final Future<String> producer = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
Thread.sleep(5000);
return "done";
}
});
// consumers
for (int i = 0; i < 3; i++) {
final int _i = i;
executor.submit(new Runnable() {
#Override
public void run() {
System.out.println("Consumer "+_i+" starts.");
try {
String value = producer.get();
System.out.println("Consumer "+_i+" ends: "+value);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
If you run this, you should see all the consumer threads printing out their starting message, then a pause, then the consumer threads print out they're done. Obviously you'd have to change whatever is producing the value of getObject() into a Callable but I'd bet good money this will simplify the code since now it'll be structured procedurally instead of storing the result of a computation in a shared variable. I'm also more confident it's thread safe than of any code using manual locking.

One way of doing it is using wait() instead of condition.await(). Then use notifyAll() to wake up the threads.
Ideally, you would continue using the condition object that causes the thread to sleep and invoke the method signalAll() to wake up all the threads.
In you code I would just add:
public Object getObject(){
lock.lock();
try {
while (check)){
condition.await();
}
condition.signalAll();
return returnObjectAndSetCheckToFalse();
} finally {
lock.unlock();
}
}
I would even look at the possibility of using the condition.signalAll() inside the returnObjectAndSetCheckToFalse() method instead of before the return statement.

Indeed it it is contradictory. What you want to achieve is problematic. You want threads waiting on the condition should get result and continue, but a thread that invokes getObject just after notification would not. At least, it is unfair. Whether that thread manages to call getObject before notification or not, is pure random thing. You should decrease indeterminism, not to increase it.

Related

What is the preferred way to use interrupt a Java Runnable and run clean up?

General question about design here. I have a few threads that need to stay running in the background, basically some database upload/failure handling tasks. The all have the following flow pattern:
public class Worker implements Runnable {
private AtomicBoolean isAlive = new AtomicBoolean(true);
....
public void run() {
while (isAlive.get()) {
// do some work here, slightly heavy
if (Thread.interrupted()) {
// checking Thread.interrupted() as the code above
// can take a while and interrupt may happen before
// it gets here.
isAlive.setBoolean(false);
break; // to exit faster
}
try { Thread.sleep(sleepTime); }
catch (InterruptedException e) {
isAlive.setBoolean(false);
break; // to exit faster
}
}
cleanUp(); // e.g. close db connections etc
}
}
Now I would like to be able to interrupt the threads so it can break out of the while loop gracefully and run the cleanUp() method.
There are many ways to do this, to list a few:
Kick the Runnables off in Threads, then use the interrupt() method:
List<Thread> threadList =...
for (int i < 0; i < threadCount; i++) {
Thread t = new Thread(new Worker());
threadList.add(t);
t.start()
}
// later
for (Thread t : threadList) { t.interrupt(); }
ThreadPoolExecutor, then use shutdownNow():
ThreadPoolExecutor executor = new ....;
executor.execute(new Worker());
// some lines else later
executor.shutdownNow(); // shutdown() doesn't interrupt?
What is the way to handle this type of workflow and why? All ideas welcome.
Over all, I personally think setting isAlive to false is the cleanest.
According to my knowledge, interrupt() is native code, which is a reason itself to stay away from.
Don't forget to set the boolean to volatile.
I think both are acceptable approaches. If you have a lot of threads, I'd go with the threadpool approach for the easier management. If you just have one (maybe two) threads, I would interrupt them individually.
As MouseEvent stated, it would be cleaner to not use the interrupt and use that isAlive variable (which seems to be pointless in your implementation). This, however, implies that you need to close or shutdown each of the instances (still a good approach)
Also, I would surround the entire method in a try-catch-finally statement where you catch the interruption and have the cleanup in the finally clause.

Java: two WAITING + one BLOCKED threads, notify() leads to a livelock, notifyAll() doesn't, why?

I was trying to implement something similar to Java's bounded BlockingQueue interface using Java synchronization "primitives" (synchronized, wait(), notify()) when I stumbled upon some behavior I don't understand.
I create a queue capable of storing 1 element, create two threads that wait to fetch a value from the queue, start them, then try to put two values into the queue in a synchronized block in the main thread. Most of the time it works, but sometimes the two threads waiting for a value start seemingly waking up each other and not letting the main thread enter the synchronized block.
Here's my (simplified) code:
import java.util.LinkedList;
import java.util.Queue;
public class LivelockDemo {
private static final int MANY_RUNS = 10000;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < MANY_RUNS; i++) { // to increase the probability
final MyBoundedBlockingQueue ctr = new MyBoundedBlockingQueue(1);
Thread t1 = createObserver(ctr, i + ":1");
Thread t2 = createObserver(ctr, i + ":2");
t1.start();
t2.start();
System.out.println(i + ":0 ready to enter synchronized block");
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
t1.join();
t2.join();
System.out.println();
}
}
public static class MyBoundedBlockingQueue {
private Queue<Object> lst = new LinkedList<Object>();;
private int limit;
private MyBoundedBlockingQueue(int limit) {
this.limit = limit;
}
public synchronized void addWhenHasSpace(Object obj) throws InterruptedException {
boolean printed = false;
while (lst.size() >= limit) {
printed = __heartbeat(':', printed);
notify();
wait();
}
lst.offer(obj);
notify();
}
// waits until something has been set and then returns it
public synchronized Object getWhenNotEmpty() throws InterruptedException {
boolean printed = false;
while (lst.isEmpty()) {
printed = __heartbeat('.', printed); // show progress
notify();
wait();
}
Object result = lst.poll();
notify();
return result;
}
// just to show progress of waiting threads in a reasonable manner
private static boolean __heartbeat(char c, boolean printed) {
long now = System.currentTimeMillis();
if (now % 1000 == 0) {
System.out.print(c);
printed = true;
} else if (printed) {
System.out.println();
printed = false;
}
return printed;
}
}
private static Thread createObserver(final MyBoundedBlockingQueue ctr,
final String name) {
return new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(name + ": saw " + ctr.getWhenNotEmpty());
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
}, name);
}
}
Here's what I see when it "blocks":
(skipped a lot)
85:0 ready to enter synchronized block
85:0 entered synchronized block
85:2: saw hello
85:1: saw world
86:0 ready to enter synchronized block
86:0 entered synchronized block
86:2: saw hello
86:1: saw world
87:0 ready to enter synchronized block
............................................
..........................................................................
..................................................................................
(goes "forever")
However, if I change the notify() calls inside the while(...) loops of addWhenHasSpace and getWhenNotEmpty methods to notifyAll(), it "always" passes.
My question is this: why does the behavior vary between notify() and notifyAll() methods in this case, and also why is the behavior of notify() the way it is?
I would expect both methods to behave in the same way in this case (two threads WAITING, one BLOCKED), because:
it seems to me that in this case notifyAll() would only wake up the other thread, same as notify();
it looks like the choice of the method which wakes up a thread affects how the thread that is woken up (and becomes RUNNABLE I guess) and the main thread (that has been BLOCKED) later compete for the lock — not something I would expect from the javadoc as well as searching the internet on the topic.
Or maybe I'm doing something wrong altogether?
Without looking too deeply into your code, I can see that you are using a single condition variable to implement a queue with one producer and more than one consumer. That's a recipe for trouble: If there's only one condition variable, then when a consumer calls notify(), there's no way of knowing whether it will wake the producer or wake the other consumer.
There are two ways out of that trap: The simplest is to always use notifyAll().
The other way is to stop using synchronized, wait(), and notify(), and instead use the facilities in java.util.concurrent.locks.
A single ReentrantLock object can give you two (or more) condition variables. Use one exclusively for the producer to notify the consumers, and use the other exclusively for the consumers to notify the producer.
Note: The names change when you switch to using ReentrantLocks: o.wait() becomes c.await(), and o.notify() becomes c.signal().
There appears to be some kind of fairness/barging going on using intrinsic locking - probably due to some optimization. I am guessing, that the native code checks to see if the current thread has notified the monitor it is about to wait on and allows it to win.
Replace the synchronized with ReentrantLock and it should work as you expect it. The different here is how the ReentrantLock handles waiters of a lock it has notified on.
Update:
Interesting find here. What you are seeing is a race between the main thread entering
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
while the other two thread enter their respective synchronized regions. If the main thread does not get into its sync region before at least one of the two, you will experience this live-lock output you are describing.
What appears to be happening is that if both the two consumer threads hit the sync block first they will ping-pong with each other for notify and wait. It may be the case the JVM gives threads that are waiting priority to the monitor while threads are blocked.

Are wait() and notify() unreliable despite of synchronized?

I recently discovered that using synchronized won't prevent any dead locks.
E.g. within this code:
ArrayList <Job> task;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
synchronized(this){
notify();
}
}
public void run(){
while(true){
for (int = 0;i<tasks.size();i++){
synchronized(tasks){
Job job = tasks.get(i);
}
//do some job here...
}
synchronized(this){
wait(); //lock will be lost...
notifier = false; //lock will be acquired again after notify()
}
}
}
Now, what is the problem? Well, if the running thread isn't waiting, he won't see any notifications (i.e. notify() calls), therefore he may run into a dead lock and not handle the tasks he received! (Or he may handle them too late...)
Therefore I implemented this code:
private volatile boolean notifier = false;
ArrayList <Job> task;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
synchronized(this){
notifier = true;
notify();
}
}
public void run(){
while(true){
for (int = 0;i<tasks.size();i++){
synchronized(tasks){
Job job = tasks.get(i);
}
//do some job here...
}
synchronized(this){
if(!notifier){
wait(); //lock will be lost...
notifier = false; //lock will be acquired again after notify()
}
}
}
}
Is this correct or am I missing something? And can it be done easier?
Now, what is the problem? Well, if the running thread isn't waiting, he won't see any notifications (i.e. notify() calls), therefore he may run into a dead lock and not handle the tasks he received!
Right. This is not a case of being "unreliable" but rather a case of language definition. The notify() call does not queue up notifications. If no threads are waiting then the notify() will effectively do nothing.
can it be done easier?
Yes. I'd look into using BlockingQueue -- a LinkedBlockingQueue should work well for you. One thread call pull from the queue and the other can add to it. It will take care of the locking and signaling for you. You should be be able to remove a large portion of your hand written code once you start using it.
I was tricked by your question at first.
Your synchronize(this) on thread object don't make sense. I in the past also do this stuff to make wait() not throwing compilation error.
Only synchronize(tasks) make sense as you are waiting and want to acquire this resources.
Having a for loop, it is bad design. In the consumer-producer problem. get a job at the same time remove a job. better fetch a job once at a time.
public void do(Job job){
synchronized(tasks){
tasks.add(job);
notify();
}
}
public void run(){
Job job;
while(true){
//This loop will fetch the task or wait for task notification and fetch again.
while (true){
synchronized(tasks){
if(tasks.size()>0){
job = tasks.getTask(0);
break;
}
else
wait();
}
}
//do some job here...
}
}
The result actually isn't a dead lock, but rather a starvation of the task/job itself. Because no threads are "locked", the task just won't be done until another thread calls do(Job job).
Your code is almost correct - beside the missing exception handling when calling wait() and notify(). But you may put the task.size() within a synchronisation block, and you may block the tasks during the hole process because a deletion of a job within tasks by another thread would let the loop to fail:
...
while(true){
synchronized(tasks){
for (int = 0;i<tasks.size();i++){ //could be done without synchronisation
Job job = tasks.get(i); //if noone deletes any tasks
}
//do some job here...
}
...
Just note that your code is blocking. Non-blocking might be faster and look like this:
ArrayList <Job> tasks;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
}
public void run(){
while(true){
int length;
synchronized(tasks){
length = tasks.size();
}
for (int = 0;i<length;i++){
Job job = tasks.get(i); //can be done without synchronisation if noone deletes any tasks...otherwise it must be within a synchronized block
//do some job here...
}
wait(1); //wait is necessary and time can be set higher but never 0!
}
}
What can we learn? Well, within non-blocking threads no notify(), wait() and synchronized are needed. And setting wait(1) doesn't even use more CPU when idle (don't set wait(0) because this would be treated as wait().
However, be careful because using wait(1) may be slower than using wait() and notify(): Is wait(1) in a non-blocking while(true)-loop more efficient than using wait() and notify()? (In other words: Non-blocking might be slower than blocking!)

Stopping thread Immediately

I want to stop a running thread immediately. Here is my code:
Class A :
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
Class B:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
My problem is that i need to be able to stop the thread in Class B even before the thread is finished. I've tried interrupt() method, but that doesn't stop my thread. I've also heard about using shared variable as a signal to stop my thread, but I think with long recursive and for-loop in my process, shared-variable will not be effective.
Any idea ?
Thanks in advance.
Thread.interrupt will not stop your thread (unless it is in the sleep, in which case the InterruptedException will be thrown). Interrupting basically sends a message to the thread indicating it has been interrupted but it doesn't cause a thread to stop immediately.
When you have long looping operations, using a flag to check if the thread has been cancelled is a standard approach. Your methodA can be modified to add that flag, so something like:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
Then a cancel method can be added to set that flag
public void cancel() {
cancelled = true;
}
Then if someone calls runEverything on B, B can then just call cancel on A (you will have to extract the A variable so B has a reference to it even after runEverything is called.
I think you should persevere with using Thread.interrupt(). But what you need to do to make it work is to change the methodA code to do something like this:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
This is equivalent declaring and using your own "kill switch" variable, except that:
many synchronization APIs, and some I/O APIs pay attention to the interrupted state, and
a well-behaved 3rd-party library will pay attention to the interrupted state.
Now it is true that a lot of code out there mishandles InterruptedException; e.g. by squashing it. (The correct way to deal with an InterruptedException is to either to allow it to propagate, or call Thread.interrupt() to set the flag again.) However, the flip side is that that same code would not be aware of your kill switch. So you've got a problem either way.
You can check the status of the run flag as part of the looping or recursion. If there's a kill signal (i.e. run flag is set false), just return (after whatever cleanup you need to do).
There are some other possible approaches:
1) Don't stop it - signal it to stop with the Interrupted flag, set its priority to lowest possible and 'orphan' the thread and any data objects it is working on. If you need the operation that is performed by this thread again, make another one.
2) Null out, corrupt, rename, close or otherwise destroy the data it is working on to force the thread to segfault/AV or except in some other way. The thread can catch the throw and check the Interrupted flag.
No guarantees, sold as seen...
From main thread letsvsay someTask() is called and t1.interrput is being called..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o/P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
Only t1.interuuption will not be enough .this need check the status of Thread.interrupted() in child thread.

Allowing only two thread to operate on a function

I have an unusual problem.
I have a function, operation in this function can be done by two threads at a time.
static int iCount = 1;
public synchronized void myFunct(){
while(iCount >= 3)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
iCount++;
//Do Stuffs
//After operation decrement count
iCount --;
notifyAll();
}
What i am trying to do is, i want to allow only two threads to do some operation, and other threads must wait.
But here first two threads increment the count and does the operation and other threads go for an wait state but do not get the notification.
I guess i am overlooking something.
Sounds like you want to use a Semaphore, you always call acquire() before doing your operation, and then release() in a finally block.
private static final Semphore semaphore = new Semaphore(2);
public static void myFunct() throws InterruptedException {
semaphore.aquire();
try {
// do stuff
} finally {
semaphore.release();
}
}
Your function is synchronized, so only one thread at a time can be in it.
I'm not sure I understand your question... But if you want to allow two threads to go somewhere at once, have a look at Semaphore.
Is this a singleton class?
If not then it's a problem because many concurrent instances may change the value of icounter and in addition they will block on it forever because no thread will be able to call notify on their instance object.
Anyway you should move the sync inside the function and lock iCount and not the instance, also make it volatile.
public void myFunct(){
synchronized(iCount) {
while(iCount >= 3)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
iCount++;
}
//Do Stuffs
//After operation decrement count
synchronized(iCount) {
iCount--;
}
notifyAll();
Why aren't you just using a Semaphore?
An alternative might be to use a ThreadPoolExecutor with a maximum of two threads.
You need java.util.concurrent.Semaphore, initialized with 2 permits.
As for your current code - threads may cache values of variables. Try adding the volatile keyword.
There are many problems with this code. Among them:
You have no real control on the number of threads running myFunct, since the method is synchronized on the instance level, while the counter is static. So N different threads operating on N different instances may run the same method concurrently.
Manipulating the counter by multiple threads is not thread safe. Consider synchronizing it or using AtomicInteger.
Regarding the limit on the number of threads, consider using the Semaphore class.

Categories