Wait until all threads are waiting before first notify - java

In MyClass I create several threads in a loop like so:
for(int i = 0; i < 4; i++)
{
threads[i] = new Thread(new MyRunnable(lock));
threads[i].start();
}
where lock is a property of MyClass, and each of these threads, in their run method, calls lock.wait().
After I've created these threads I want to assign one of them control of the lock. I tried simply putting lock.notify() after the loop, but this runs too soon - although it's after the loop, none of the threads have yet executed lock.wait(), so they all miss the lock.notify(), and then wait indefinitely for another one that never comes.
I can halt execution of the main thread for a bit, e.g. execute Thread.sleep(1000) before I call lock.notify(). This works as it gives the threads a chance to get to the waiting stage before notifying them. But this doesn't seem very elegant, and obviously I'd rather not halt the main execution of my program like this.
How should I achieve this?

You could use some more high-level constructs from the concurrency package, such as a Semaphore.
So you'd set up the Semaphore with a single "permit" before your loop, pass it to your threads, and then all of them would try to "acquire" that permit (which only one of them can do, the others will fail at that).
Even Semaphore is kind of low-level, usually you can find something even more tailored to your actual application, such as blocking queues or concurrent collections.

Have a look at Thread.join() method which can help you to make wait current thread, until thread which invoked this method is not completed.
Example:
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start();
t1.join();
t2.start();
Here t2 will wait for the completion of t1. More about it, you can read here.

Related

CountDownLatch in Java need additional synchronization?

Let's say I have the code below:
public class CountDownLatchExample { // Note : Exception handling ommited
void main(){
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N_PARTIES);
for(int i = 0; i < N_PARTIES; i++){ // create and start threads
new Thread(() -> {
startSignal.await(); // Wait startSignal before doing Work
doWork();
doneSignal.countDown();
}).start();
}
// (...) do something else // Don't let run yet
startSignal.countDown(); // Let all threads proceed
// (...) do something else
doneSignal.await(); // Wait for all threads to finish
}
}
The main thread creates and starts the worker threads. In the run method, the other threads wait until the main thread call startSignal.countDown(), and then they can call doWork() and doneSignal.countDown().
I know that there is an happens-before relationship between the countDown() called by a thread and threads that return from await, then if a thread call doneSignal.countDown(), what it did is visible to all the other threads.
But my question is if the run() method is executed sequentially or not, and if we need to add synchronization??
Because when startSignal.countDown() is called, all the threads can execute the run method, but suppose that in the doWork() method there are some shared variables that change, or also simply that executing run() concurrently, there are maybe three threads that executed doWork() concurrently, and then two of them are scheduled out right before doneSignal.countDown(), and the third one call doneSignal.countDown(). Here the happens-before relationship is a little bit useless if the other two threads have already executed doWork() and they have only to call doneSignal.countDown(), because they didn't see what the third one did, because they executed doWork() "together".
The CountDownLatch does not guarantee per the mutual exclusion of the accesses to the share data, rather this mechanism is used to synchronized -- in the sense of one waiting for the other -- parallel task among each other. Similar to the functionality provided by a Cyclic barrier. Actually, as you have described this is the reason why you are using this mechanism in your code; to coordinate the execution of the main and the remaining threads.
If the doWork() method contains shared state among threads, which is modified concurrently, then you might have race-condition. Hence, you need to ensure mutual exclusion of that shared using for instance the synchronized clause.

Main thread wait for other threads

After seaching a lot and not finding a concrete answer
If I have two threads started:
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start();
t2.start();
After starting the threads I need the main thread to wait for these two thread to finish before printing the final result
How can I make the main thread wait for both t1 and t2?
A plain wait() would be enough?
Add
t1.join();
t2.join();
in your thread which should wait till t1 and t2 will finish their tasks (in your case call it from your main thread).
The answer depends...
You could
Use a CountDownLatch which is probably the simplest solution.
This way you would simply wait on the latch until it has been signaled the prescribed number of times (by each Thread terminating). This scales quite nicely as you increase the number of threads...
You could
Use join, but it would become tedious as you add more threads
You could
Add each Thread to a List, loop through the list, removing those threads that are no longer alive and keep looping until the List is empty, but that's a rather heavy handed approach.
You could
Combine the above solution with some kind of monitor lock which the loop would wait on and each Thread would notify when they complete, but it's not much cleaner and you could still end up waiting for non-existent threads...
You could
Use an ExecutorService and either use it's invokeAll and/or shutdown methods. See Executors for more details. This also scales quite nicely and even has the added benefit of allowing you to use a Thread pool to better manage the system resourcs
Check out the Thread#join method.
Also, you might find using an ExecutorService (and friends) helpful. Its essentially thread pool/management and provides a lot of conveniences and IMO a cleaner API than threads. Barrier to entry is low...
You want Thread#join(). wait() is for signalling, join() is to wait for the thread to finish.

How to end a thread after coming out of a for loop

So I have a program that prints Hello and Goodbye by using 2 threads.
I need to print Hello 100 times and Goodbye 100 times.
This is working fine, however, after it prints, the program hangs and doesn't finish.
I have a feeling it is because the threads aren't finishing up.
I was wondering what the best way to do this is?
So my main is like this
public static void main(String [] args)
{
Object lock = new Object();
new HelloThread(lock).start();
new GoodbyeThread(lock).start();
}
And here is the HelloThread class. GoodbyeThread looks the same:
class HelloThread extends Thread
{
private Object lock;
private boolean isRunning = false;
HelloThread(Object l)
{
this.lock = l;
}
public void run()
{
for(int i = 0; i < 100; i++)
{
synchronized(lock)
{
isRunning = true;
System.out.println("Hello");
lock.notify();
try
{
lock.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
I was thinking there might be a way to have the isRunning variable be used to close the thread, however I'm not sure what the best way to go about it.
Thanks for any help
The for loop isn't important, the key things happen in the last iteration. It is very probable that one of the threads will enter its wait() after the other thread has already executed its notify(), thus missing the only chance to break out of that wait().
Your GoodbyeThread is waiting for your HelloThread to send a notify().
What is likely happening at i == 99:
HelloThread prints "Hello" calls notify(), then calls wait()
GoodbyeThread prints "Goodbye" calls notify() [here HelloThread exits the for loop and terminates], then calls wait().
Nothing will ever call notify() to end the wait() of the GoodbyeThread.
One fix would be to only call wait() if i < 99.
This is working fine, however, after it prints, the program hangs and doesn't finish. I have a feeling it is because the threads aren't finishing up.
If the thread is leaving the run() method then it will finish up. I suspect that your thread is stuck on lock.wait() after the 100th printing of "Hello". If you use jconsole or dump a thread stack trace you should be able to see where the threads are stuck.
One thing to realize is that if you call lock.notify() the only time the other thread will get the notification is if it is in lock.wait(). Notify calls do not queue up.
As mentioned above: the thread is deadlocking because at least one of them is still waiting for the notify() call.
Imagine you only had one run to do (print "Hello world" only once):
Thread A starts, prints "Hello", then runs notify(), but no one is listening, then wait().
Thread B starts, prints "World", then runs notify().
Thread A wakes up and tries to regain the monitor lock but this one is still hold by Thread B, so Thread A has to wait further.
Thread B runs wait(), releasing the monitor.
Thread A wakes up again, regains the monitor and finishes the loop.
Thread B still waits, but is never woken up.
This can be solved through an exit notify like this:
for(int i = 0; i < 100; i++) {
// ...
}
synchronized (lock) {
lock.notifyAll();
}
The wait/notify constructs are the most basic tools for threading, and not well suited for many threading problems out there, as they very often can result in deadlocks or worse. For easier and less error-prone threading concepts, you should use the concurrent package, which has ready-made tools available for most problems out there.
But it is necessary to be familiar with these tools, and you absolutely must design your code around these tools and not vice versa. An existing program cannot be just filled up with multi-threading to make it faster, it needs to be designed for it before you even write the first line of code. Otherwise you run into many issues, including that your result might be slower than a single-threaded execution would have been.

What is the difference between join and CountDownLatch?

When waiting for other threads to finish, we can use either join or CountdownLatch. What are the pros and cons of using either of those two mechanisms?
You can only use Thread.join if you're handling the threads yourself. Most people choose not to deal with the minutia of thread handling directly, and instead use an ExecutorService to handle it for them. ExecutorServices do not directly reveal how they are executing tasks, so you would have to use a CountDownLatch: (Assuming you don't want to just shutdown the whole service, that is.)
ExecutorService service = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(5);
for(int x = 0; x < 5; x++) {
service.submit(new Runnable() {
public void run() {
// do something
latch.countDown();
}
});
}
latch.await();
Another difference is after join(), thread can be unblocked only when joined thread has finished its execution while in CountDownLatch a thread can decrease the count anytime either on completion of thread or in between based on any condition.
This way we can get better control over unblocking of the thread instead of solely depending on the completion of joined thread.
join() is waiting for another thread to finish while CountDownLatch is designed for another purpose. If using CountDownLatch, You don't have to have reference of threads for which you are waiting as we have to do using join(). Let's assume you want to start a game when at least 2 players should be available. You can use countdownlatch in this case. But you can't achieve this using join easily because you don't have another thread(player in this case) on which you can write join().
A CountdownLatch is task-oriented - it's thread-agnostic. A whole pile of unrelated sets of tasks can be submitted to a threadPool and a CountdownLatch will ensure that each set notifies the originator of completion. Join() is an annoying abberation that links tasks to threads and, simply put, should never have entered the language in the first place. Sadly, a large, steaming pile of thread-tutorials mention Join() on the first page, thereby introducing threads to newbies as a deadlock-generator and generating thread-funk :(
CountdownLatchallows you to change the implementation of Item to maybe submit to an Executor service instead of using Threads directly.
The CountDownLatch class allows us to coordinate the starting and stopping of threads. Typical uses are as follows:
We can make several threads start at the same time;
We can wait for
several threads to finish (whereas, for example, the Thread.join()
method only lets you wait for a single thread).
You can have a look at this -> http://javahowto.blogspot.com/2011/08/when-to-join-threads-with.html
And this ->
A CountDownLatch's latch.await() method vs Thread.join()

java threads : producer - consumer

I have some developpements to do and I try to see if there is a desing pattern to use.
The problem is simple:
I have a main thread that launches many treads. The main thread must wait for each thread to finish and then doing something else.
The existing code it's a bit ugly. I have a while loop that check a thread group to see if is something running:
//launch threads
.....
//wait for threads to finish
while (ThreadRepository.getInstance().isActiveThreadGroup(myGroupId)) {
Thread.sleep(5000);
}
//doing something else
So, as you see, the while loop keeps running until no threads running.
I was thinking at the pattern producer-consumer and I would like to do something like that:
Using some BlockingQueue for instance, and each thread put (or take) something in it.
Instead of having the while and sleep I would like to have something like
myQueue.take() but something to wait for the queue to be empty.
When empty, it means no threads running.
I try to search on the Internet but I did not found something that matches my problem.
Does anyone know the most efficient to solve my problem ?
There are two easy ways to have one thread wait for N threads to finish:
Make the main thread call join() on all the other threads. join() returns when a thread finishes, or has already finished
Create a CountDownLatch initialized to N, pass this latch to all the threads, make each thread call countDown() on the latch when it has finished, and make the main thread call await() on the latch. This second technique is a bit harder than the first one, but is also more flexible and reusable, and allows being awaken after some delay, even if the N threads have not finished yet.
You can use BlockingQueue as follows:
each child thread puts a message in the queue when finished
the main thread takes messages from the queue and counts them. When the number of messages equals the number of threads, all threads has finished.

Categories

Resources