Wait for one of several threads - java

I have a java application where the main-thread starts 2 other threads.
If one of these threads terminates, the main-thread may start another thread depending on the result of the terminated thread.
Example:
The main-thread creates 2 threads: A and B. Thread A will load a picture and thread B will load another picture. If A terminates and loaded the picture successfully a new Thread C will be created which does some other stuff and so on.
How can i do this? I do not want to use busy waiting in the main thread and check every 100ms if one of the two threads has finished.
I think i cannot use a thread pool because the number of active threads (in this case A and B) will vary extremely and it's the main-threads dicision to create a new thread or not.
This is rough sketch of the "busy waiting" solution:
public class TestThreads {
private class MyThread extends Thread {
volatile boolean done = false;
int steps;
#Override
public void run() {
for (int i=0; i<steps; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException exc) { }
}
done = true;
synchronized (this) {
notify();
}
}
public void waitFor(long ms) {
synchronized (this) {
try {
wait(ms);
} catch (InterruptedException exc) { }
}
}
}
public void startTest() {
MyThread a = new MyThread();
a.steps = 6;
a.start();
MyThread b = new MyThread();
b.steps = 3;
b.start();
while (true) {
if (!a.done) {
a.waitFor(100);
if (a.done) {
System.out.println("C will be started, because A is done.");
}
}
if (!b.done) {
b.waitFor(100);
if (b.done) {
System.out.println("C will be started, because B is done.");
}
}
if (a.done && b.done) {
break;
}
}
}
public static void main(String[] args) {
TestThreads test = new TestThreads();
test.startTest();
}
}

This sounds like a classic case for using a ThreadPoolExecutor for performing the tasks concurrently, and wrapping it with an ExecutorCompletionService, for collecting the results as they arrive.
For example, assuming that tasks contains a set of tasks to execute in parallel, each returning a String value when it terminates, the code to process the results as they become available can be something like:
List<Callable<String>> tasks = ....;
Executor ex = Executors.newFixedThreadPool(10);
ExecutorCompletionService<String> ecs = new ExecutorCompletionService<String>(ex);
for (Callable<String> task : tasks)
ecs.submit(task);
for(int i = 0; i < tasks.size(); i++) {
String result = ecs.take().get();
//Do something with result
}
If you include the identity of the task as a part of the returned value, then you can make decisions depending on the completion order.

Check Semaphore
A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it
So, whenever you thread finishes, it frees one permit, which is then acquired by the main thread

You should use a thread pool. In a thread pool, you have a fixed number of threads and tasks are kept in a queue; whenever a thread is available, a task is taken off the queue and executed by that thread.
Here is a link to the Sun tutorial on thread pooling.
Edit: just noticed that you wrote in your answer that you think you cannot use thread pooling. I don't see why this is the case. You can set threads to be created on-demand rather than all at once if you are worried about creation overhead, and once created an idle thread is not really going to hurt anything.
You also say that it's the main thread's decision to create a new Thread or not, but does it really need to be? I think that may just overcomplicate things for you.

Is there a reason to control the thread execution directly instead of using something like
ExecutorService?
#danben got there first, but I fell into the same pooling trap.

A lot of the complexity in your code is that the main thread is trying to wait on two different objects. There's nothing which says you can't use wait and notify on another object, and if your tasks are ( A or B ) then C, the code below will work - wait on a reference which is set to indicate the first task to complete.
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class BiggieThreads
{
private static class MyTask implements Runnable
{
final int steps;
final AtomicReference<MyTask> shared;
final String name;
MyTask ( int steps, AtomicReference<MyTask> shared, String name )
{
this.shared = shared;
this.steps = steps;
this.name = name;
}
#Override
public void run()
{
for ( int i = 1; i <= steps; i++ ) {
System.out.println ( "Running: " + this + " " + i + "/" + steps);
try {
Thread.sleep ( 100 );
} catch ( InterruptedException exc ) { }
}
// notify if this is the first to complete
if ( shared.compareAndSet ( null, this ) )
synchronized ( shared ) {
shared.notify();
}
System.out.println ( "Completed: " + this );
}
#Override
public String toString ()
{
return name;
}
}
public void startTest() throws InterruptedException
{
final ExecutorService pool = Executors.newFixedThreadPool ( 3 );
final AtomicReference<MyTask> shared = new AtomicReference<MyTask>();
Random random = new Random();
synchronized ( shared ) {
// tasks launched while lock on shared held to prevent
// them notifying before this thread waits
pool.execute ( new MyTask ( random.nextInt ( 5 ) + 3, shared, "a" ) );
pool.execute ( new MyTask ( random.nextInt ( 5 ) + 3, shared, "b" ) );
shared.wait();
}
System.out.println ( "Reported: " + shared.get() );
pool.shutdown();
}
public static void main ( String[] args ) throws InterruptedException
{
BiggieThreads test = new BiggieThreads ();
test.startTest();
}
}
I'd tend to use a semaphore for this job in production, as although the wait is quite simple, using in semaphore puts a name to the behaviour, so there's less to work out when you next read the code.

Related

Weird Behaviour on wait() and notifyAll()

I found myself puzzled with this behaviour for wait() and notifyAll():
import java.util.LinkedList;
import java.util.Queue;
class Producer implements Runnable {
Queue<Integer> sharedMessages;
Integer i = 0;
Producer(Queue<Integer> sharedMessages) {
this.sharedMessages = sharedMessages;
}
public void produce(Integer i) {
synchronized (sharedMessages){
System.out.println("Producing message " + i);
this.sharedMessages.add(i);
}
}
public void run(){
synchronized (sharedMessages) {
while (i < 100) {
produce(i++);
}
}
}
}
Consumer:
class Consumer implements Runnable{
Queue<Integer> sharedMessages;
Consumer(Queue<Integer> sharedMessages) {
this.sharedMessages = sharedMessages;
}
public void consume() {
synchronized (sharedMessages) {
System.out.println(sharedMessages.remove() + " consumed by " + Thread.currentThread().getName().toString());
}
}
#Override
public void run(){
synchronized (sharedMessages){
while(sharedMessaged.size() > 0){
System.out.println(Thread.currentThread().getName() + " going to consume");
consume();
try {
sharedMessages.wait();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + ": I was interrupted from my sleep!");
}
sharedMessages.notifyAll();
}
}
}
}
Here's how I'm creating the threads:
public class Main {
public static void main(String[] args) {
Queue<Integer> sharedMessages = new LinkedList<>();
new Thread(new Producer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
}
}
The output looks something like this:
Producing message 0
Producing message 1
...
Producing message 98
Producing message 99
Thread-6 going to consume
0 consumed by Thread-6
Thread-5 going to consume
1 consumed by Thread-5
Thread-4 going to consume
2 consumed by Thread-4
Thread-3 going to consume
3 consumed by Thread-3
Thread-2 going to consume
4 consumed by Thread-2
Thread-1 going to consume
5 consumed by Thread-1
And then the application keeps running, without consumers consuming any messages after 5.
Since wait() and notifyAll() are created on the same monitor, sharedMessages, and the while loop keeps on running, shouldn't the consumer threads keep on running, alternatively consuming messages?
NOTE: This question is NOT about a Bounded Blocking Queue / typical Producer Consumer. I'm trying to gain a better understanding of wait() and notifyAll and this behaviour caught my attention. I am probably missing something here, and I am looking for answers pointing out what I am missing and NOT a certain another way of doing it.
Your Producer thread locks the queue, then adds 100 messages without ever releasing the lock, and finally releases the lock before terminating, without ever notifying anyone.
Your 6 Consumer threads will each consume a message, then call wait().
At this point, the Producer thread has ended, and the 6 Consumer threads are waiting.
Who did you envision would be notifying them to wake them up?
Your current code is producing its output, because all your consumers will consume at most one item - depending on if they can run before or after your producer - and then they will wait unconditionally. There is nothing to wake them up, so they won't run again.
So, the behaviour you see is expected for the code you have written, as the only notifyAll() calls happens by consumers after their unconditional wait, so in essence never (except under spurious wake ups). In addition, your overly large synchronized blocks hinder the threads from running concurrently.
The primary changes you need to make are:
Reduce the size of your synchronized blocks (ideally it should only cover producing or consuming a single item)
Do not wait unconditionally, only wait when there are no items in the queue and the producer is still active (you will need a way to signal the producer is done)
Have the producer call notifyAll() after each item (alternatively, call notify() after each item, and notifyAll() after all items have been produced).
You've already got two good answers, but if you want to compare your next solution to something, here's some code I had wrote a while ago for a simple example. It's lightly tested but seems to work OK.
Notice instead of a Queue I implement my own circular buffer. It does the same thing, but its implementation is a little closer to what you might see in some low level (and optimized) object.
public class ProducerConsumer {
public static void main(String[] args) throws InterruptedException {
CircularBuffer buffer = new CircularBuffer();
Counter producer1 = new Counter( buffer, 1000 );
Counter producer2 = new Counter( buffer, 2000 );
Counter producer3 = new Counter( buffer, 3000 );
Counter producer4 = new Counter( buffer, 4000 );
ExecutorService exe = Executors.newCachedThreadPool();
exe.execute( producer1 );
exe.execute( producer2 );
exe.execute( producer3 );
exe.execute( producer4 );
Printer consumer = new Printer( buffer );
exe.execute( consumer );
Thread.sleep( 100 );// wait a bit
exe.shutdownNow();
exe.awaitTermination( 10, TimeUnit.SECONDS );
}
}
// Producer
class Counter implements Runnable {
private final CircularBuffer output;
private final int startingValue;
public Counter(CircularBuffer output, int startingValue) {
this.output = output;
this.startingValue = startingValue;
}
#Override
public void run() {
try {
for( int i = startingValue; ; i++ )
output.put(i);
} catch (InterruptedException ex) {
// exit...
}
}
}
class CircularBuffer {
private final int[] buffer = new int[20];
private int head;
private int count;
public synchronized void put( int i ) throws InterruptedException {
while( count == buffer.length ) wait();// full
buffer[head++] = i;
head %= buffer.length;
count++;
notifyAll();
}
public synchronized int get() throws InterruptedException {
while( count == 0 ) wait(); // empty
int tail = (head - count) % buffer.length;
tail = (tail < 0) ? tail + buffer.length : tail;
int retval = buffer[tail];
count--;
notifyAll();
return retval;
}
}
// Consumer
class Printer implements Runnable {
private final CircularBuffer input;
public Printer(CircularBuffer input) {
this.input = input;
}
#Override
public void run() {
try {
for( ;; )
System.out.println( input.get() );
} catch (InterruptedException ex) {
// exit...
}
}
}

Multi-threading and queuing

I kinda got the hang of threads but now I'm confused. I don't quite understand queues at all. I created a thread pool executor which initializes a set amount of threads and each of those threads input a username(string) on a website to check if its available or not. So basically I was thinking I should queue this? like queue.add(username) and queue.remove(username) or queue.take.. So I was wondering how to do queues with thread pools and which type. SynchronousQueue, BlockingQueue, or is there a better alternative? Sorry I really dont understand queuing. Ignore the bad code. Just want it to work before I make it net
FilterUsers FU = new FilterUsers();
HtmlThread[] threads = new HtmlThread[users.length];
ExecutorService executor = Executors.newFixedThreadPool(threadNo);
for (int i = 0; i < users.length; i++) {
Runnable worker = new HtmlThread(" "+i, FU, users[i]);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()){ }
this is class HtmlThread
class HtmlThread extends Thread {
private Thread t;
private String threadName;
FilterUsers filterUsers;
String users;
public HtmlThread(String tName, FilterUsers filterusers, String user) {
this.threadName = tName;
this.filterUsers = filterusers;
this.users = user;
}
public void run() {
synchronized (filterUsers) {
try {
HtmlPage page = webClient.getPage("https://website.com/account/edit");
try {
final HtmlForm form = page.getFirstByXPath("//form[#class='adjacent bordered']");
HtmlTextInput user = form.getInputByName("username");
HtmlSubmitInput b = form.getInputByValue("Submit");
user.setValueAttribute(users);
HtmlPage page2;
page2 = b.click();
String html = page2.getWebResponse().getContentAsString();
if (page2 != null) {
if (!html.contains("that username is taken")) {
Filter.validUsers.appendText(users + "\n");
}
}
} finally {
page.cleanUp();
}
} catch (Exception e) {
e.printStackTrace();
}
}
try {
System.out.println("Thread " + threadName + " Sleeping.");
Thread.sleep(3500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + threadName + " exiting.");
}
Oh, you're concerned about returning a result. Per your comment:
I updated with code. When I do this it goes way too fast. even though
I put thread to sleep for 3.5 secs. I dont think it actually sleeps.
So I thought I should add queue to prevent loss of data or w/e
Well you should have said that in your question. You could use a queue, but Java actually has it's own mechanism for returning data. You should at least try that first.
To return a result, use the Callable interface instead of Thread/Runnable. Callable works just like Runnable except you can return a value. When you submit a Callable to an executor service, you get a Future back. Just save it and then call get() to get your result. That's it, all the hard work of making queues or synchronization is already done for you.
The only thing left is checking for InterruptedException in nearly every imaginable place. ;)
/**
*
* #author Brenden Towey
*/
public class FutureExample
{
public static void main( String[] args )
{
ExecutorService exe = Executors.newFixedThreadPool(3);
List<Future<String>> results = new ArrayList<>();
for( int i = 0; i < 5; i++ )
results.add( exe.submit( new HtmlTask() ) );
try {
for( Future<String> future : results )
System.out.println( future.get() );
} catch( InterruptedException x ) {
// bail
} catch( ExecutionException ex ) {
Logger.getLogger( FutureExample.class.getName() ).
log( Level.SEVERE, null, ex );
// and bail
}
exe.shutdown();
boolean shutdown = false;
try {
shutdown = exe.awaitTermination(10 , TimeUnit.SECONDS );
} catch( InterruptedException ex ) {
// bail
}
if( !shutdown ) {
exe.shutdownNow();
try {
exe.awaitTermination( 30, TimeUnit.SECONDS );
} catch( InterruptedException ex ) {
// just exit
}
}
}
}
class HtmlTask implements Callable<String> {
#Override
public String call()
throws Exception
{
// pretend to search a website and return some result
return "200 OK";
}
}
The ideas of queues are producers and consumers. Producers put items on the queue, which the consumer threads (usually multiple threads) pick up the items and process.
SynchronousQueue - is a queue that must have a corresponding call to take() before put() returns.
BlockingQueue - is an interface. SynchronousQueue is an implementation of this BlockingQueue
So right about now you are probably very confused. I doubt you need SynchQueue. I recommend first you should read the javadoc for BlockingQueue.
Personally, you will probably want to use ArrayBlockingQueue. You should provide a capacity. Otherwise, if the producer puts more items on the queue then you will run out of memory.
I actually dont understand why you are synchronizing on filterUsers. How does the thread entering that synchronized code block modify filterUsers? Assuming that filterUsers is some type of a List implementation (that does not seem to be the case here) that you need to synchronize on so that threads block when putting or taking elements in it, you could get rid of that synchronized code block with a BlockingQueue. The BlockingQueue would block all threads doing put() when size() reaches capacity until elements are removed with a take().
So unless your synchronized code block is on a List that needs blocking, a blocking queue is not going to be of help.

Semaphores used for signaling in threads not working(concurrency issue)

in this project I am trying to do some concurrency among threads using semaphores as signaling, however the concurrency is not working at all. I can only use acquire and release and no synchronized keyword methods allowed. I read countless webpages and it says that
// do something
acquire()
release()
//do something
Which I understand but in this program I am trying to test signals with a semaphore between threads, for example user requests deposit and teller should say deposit completed.However my signals(semaphores) are not working as I want to print in order for example
I need to deposit
Deposit is complete
instead I get this
Customer0created
I need to deposit
I have withdrawn <---
Customer0joined from main
Teller0created
You wanna withdrawal? <---- (out of order)
Deposit is complete
Regardless how i reorder them or how much i read the semaphore signaling to comm threads is not working.
[code]import java.util.concurrent.Semaphore;
public class Threads {
private static Semaphore depositTransaction = new Semaphore (1, true);
private static Semaphore withdrawal = new Semaphore (1, true);
public static void main(String[] args)
{
final int customerThreads = 1;
final int tellerThreads = 1;
final int loanThreads = 1;
Customer thr[] = new Customer[customerThreads]; //
Thread cThread[] = new Thread[customerThreads]; //
for (int i= 0; i < customerThreads; i++)
{
thr[i]= new Customer(i);
cThread[i] = new Thread(thr [i]);
cThread[i].start();
}
for ( int i = 0; i < customerThreads; i++ )
{
try {
cThread[i].join();
System.out.println("Customer"+i + "joined from main");
}
catch (InterruptedException e)
{
}
}
Teller thr1[] = new Teller[tellerThreads];
Thread tThread[] = new Thread[tellerThreads];
for (int b = 0; b< tellerThreads; b++)
{
thr1[b] = new Teller(B)/>;
tThread[b]= new Thread(thr1 [b]);
tThread[b].start();
}
}
static class Customer implements Runnable
{
private int customerNumber = 0;
private int balance = 0;
Customer(int cn)
{
this.customerNumber = cn;
balance = 1000;
System.out.println("Customer"+ customerNumber + "created");
}
public void run()
{
try
{
System.out.println("I need to deposit");
depositTransaction.acquire();// signal
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
e.printStackTrace();
}
withdrawal.release();
System.out.println("I have withdrawn");
}
}
static class Teller implements Runnable
{
private int tellerNumber = 0;
Teller(int tn)
{
this.tellerNumber = tn;
System.out.println("Teller"+ tellerNumber +"created");
}
public void run()
{
try
{
System.out.println("You wanna withdrawal?");
withdrawal.acquire();
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}
depositTransaction.release();
System.out.println("Deposit is complete");
}
}
}[/code]
Here is a program that uses a semaphore to play ping pong. It is very similar to what you need for your goal. This program has one thread that will print PING, and the other prints PONG. It uses a semaphore to ensure that PING is printed first, then PONG, then PING and so on.
Notice how this program uses two semaphores, and that it starts both semaphores at zero. This means that when the threads call acquire() on it, they will block. You have been using the value of one, which means that neither thread would block and that both would rush ahead.
Now that all threads have blocked, we need to get one of them to start. We send a 'release()' signal to the semaphore that the thread that we want to start up on. That will increment the semaphore by one, and the thread blocked in acquire() will wake up and decrement it again before proceeding with its all important job of printing PING or PONG.
Remember the following about semaphores:
A semaphore contains an integer value (called a permit count)
acquire() will block until the integer value is greater than zero; when greater than zero the count will be decremented by one before exiting
release() never blocks. It only ever increments the integer value by one, and as a side effect wakes up any method that were blocked in a call to acquire().
Thus for a game of ping pong to work: (ascii art below scrolls to the right)
s1=0 -- release() --> s1=1 s1=0
s2=0 s2=0 s2=1
thread1=blocked thread1 runs -- calls s2.release() --> thread1 blocked
thread2=blocked thread2=blocked thread2 runs
Notice how the values of s1 and s2 oscilate between 0 and 1, but we do not allow them both to have the value of 1 at the same time. If they were ever to both equal 1, then both thread1 and thread2 would be able to run at the same time. Which would be known as a race condition, as the order of their execution would be unpredictable.
public class PingPong {
public static void main( String[] args ) throws InterruptedException {
final Semaphore s1 = new Semaphore(0);
final Semaphore s2 = new Semaphore(0);
final AtomicInteger countDown = new AtomicInteger( 10 );
Thread threadA = new Thread() {
public void run() {
try {
System.out.println("threadA started");
while (countDown.get() > 0) {
s1.acquire();
System.out.println( "PING" );
s2.release();
countDown.decrementAndGet();
}
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println("threadA finished");
}
};
Thread threadB = new Thread() {
public void run() {
try {
System.out.println("threadB started");
while (countDown.get() > 0) {
s2.acquire();
System.out.println( "PONG" );
s1.release();
countDown.decrementAndGet();
}
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println("threadb finished");
}
};
threadA.start();
threadB.start();
s1.release();
}
}
You are not using semaphores correctly for what you want to do. As I get it, you want to start the customer thread, then block until the teller threads finishes then finish the customer thread.
Right now your semaphore do close to nothing. They will prevent multiple customer threads from running at the same time, but within your acquire / release block, nothing happens.
If you want to synchronize between customer and teller, both classes need to use the same Semaphore
What I would suggest is this :
remove the join operation for now
create the depositTransaction semaphore with count 0, so the first acquire will block.
Start a customer thread
The thread will block waiting for a deposit
Start a teller thread
make the deposit and release the depositTransaction semaphore
the customer thread will unblock
you can now join both threads
Edit :
I don't think that your idea of adding tons of semaphore for every action is a good idea. You will end up with complex locking and deadlocks all over the place. What I would suggest is to limit the number of semaphore and implement messages between the threads. The semaphore will tell the other one (Client tells Teller and vice-versa) to check the messages after pushing one.
Start customer thread
push message that customer is waiting
signal for new customer request
wait for teller signal
Start teller thread
acquire sem for new customer request
check message
do stuff
signal customer that stuff is done
messages will then be "withdrawal customer 0" or any other action you want to implement
Would suggest you to look at one of the standard examples and rework your code. Semaphore is very easy to use and all we need to do is acquire the lock when a thread accesses the shared resource and release the lock when it it is done.
There is nice example with a producer and a consumer thread protecting a shared resource here.
Semaphore Example with a Producer and Consumer thread

Waking up a sleeping thread - interrupt() versus "splitting" the sleep into multiple sleeps

This requirement came up in my Android app, but it applies to Java in general. My app "does something" every few seconds. I have implemented this as follows (just relevant snippets - not a complete code):
Snippet1:
public class PeriodicTask {
private boolean running = true;
private int interval = 5;
public void startTask(){
while (running){
doSomething();
try{
Thread.sleep(interval * 1000);
} catch(InterruptedException e){
//Handle the exception.
}
}
}
public void stopTask(){
this.running = false;
}
public void setInterval(int newInterval){
this.interval = newInterval;
}
}
The problem with this approach, as you can see, is that setInterval() is not immediately effective. It takes effect only after a previous sleep() has completed.
Since my use case allows the end user to set the interval in fixed steps (of 1 second - from 1 to 60 seconds), I modified the implementation to sleep within a loop; and check for the new interval value every second as follows:
Snippet2:
public class PeriodicTask {
private boolean running = true;
private int interval = 5;
private int loopCounter = 0;
public void startTask(){
while (running){
doSomething();
try{
while(loopCounter < interval) {
Thread.sleep(1 * 1000);
loopCounter ++;
}
} catch(InterruptedException e){
//Handle the exception.
}
}
}
public void stopTask(){
this.running = false;
}
public void setInterval(int newInterval){
synchronized (this) {
this.interval = newInterval;
if(newInterval < loopCounter){
loopCounter = 0;
}
}
}
}
Is there a reason to not use this approach?
I recently came across the interrupt() method for this purpose. But, I couldn't exactly figure out how to use it. For one, the interrupt method, unlike the sleep method is not static. So, what Thread do I interrupt?
public void setInterval(int newInterval){
this.interval = newInterval;
//What thread do I call interrupt() on?
}
Secondly, if I do succeed in interrupting the sleeping Thread, I believe the catch block for the InterruptedException will be executed. However, I will need to call the startTask() again at this point. I am confused regarding the termination of this recursion. I have gone through several questions on SO regarding the use of interrupt(), but couldn't figure out anything that helps me.
Any pointers?
EDIT- More details on exact requirement:
MY app fetches some values using a REST call every few seconds. The update interval is configurable by the user.
Now, say the update interval has been set to 60 seconds. Snippet1 I posted would work (incorrectly) as follows:
Thread goes to sleep for 60 seconds.
Now, lets say user changes the update interval to 5 seconds. The thread is still sleeping.
The PeriodicTask would see the new update interval only after the 60 seconds have expired.
The exact requirement is that the new update intervals should be effective immediately (or at least no later than 1 second after being set - since that is what the user is likely to perceive anyway).
My Snippet2 and Snippet3 are attempts at achieving this requirement.
IIRC, in Java you can object.wait() with a timeout. Is this not what you want? If you want to change the timeout from another thread, change some 'waitValue' variable and notify(). The thread will then 'immediately' run and then wait again with the new timeout value. No explicit sleep required.
This answer helped me do the job. Posting some code on how I achieved it. Of particular importance are startTask() and setInterval().
public class PeriodicTask {
private volatile boolean running = true;
private volatile int interval = 5;
private final Object lockObj = new Object();
public void startTask() {
while (running) {
doSomething();
synchronized (lockObj) {
try{
lockObj.wait(interval * 1000);
} catch(InterruptedException e){
//Handle Exception
}
}
}
}
public void stopTask() {
this.running = false;
}
public void setInterval(int newInterval) {
synchronized (lockObj) {
this.interval = newInterval;
lockObj.notify();
}
}
}
I'm not clear on what you really want to do. Is you goal to stop the thread that is running the loop in PeriodicTask or do you just want to break the loop and allow the thread to continue? If you just want to break the loop but allow the thread to continue, consider the following example:
public class ThreadStopExample {
public static void main ( String[] args ) throws InterruptedException {
final PeriodicTask task = new PeriodicTask ();
Thread t = new Thread ( new Runnable () {
#Override
public void run () {
System.out.println ( Thread.currentThread ().getName ()
+ " starting" );
task.startTask ();
System.out.println ( Thread.currentThread ().getName ()
+ " done with the periodic task" );
}
} );
t.start ();
Thread.sleep ( 12000 );
task.setInterval ( 1 );
Thread.sleep ( 3000 );
task.stopTask ();
}
static class PeriodicTask {
private volatile boolean running = true;
private volatile int interval = 5;
public void startTask () {
running = true;
while ( running ) {
doSomething ();
try {
int count = 0;
while ( running && count++ < interval ) {
Thread.sleep ( 1000 );
}
} catch ( InterruptedException e ) {
Thread.currentThread ().interrupt ();
running = false;
break;
}
}
}
public void stopTask () {
running = false;
}
public void setInterval ( int newInterval ) {
interval = newInterval;
}
private void doSomething () {
System.out.println ( "[" + Thread.currentThread ().getName ()
+ "] Interval: " + interval );
}
}
}
This is very similar to your existing code. Note the volatile fields to ensure correct synchronization between the thread running the PeriodicTask loop and the main thread that attempts to change the interval and to stop the task (see here for links to more information on the memory model for java). As you can see, the thread that works with the PeriodicTask instance continues after the call to stop the task. Also, note that PeriodicTask will call interrupt on the current thread when it receives the interrupted exception. This ensures that the interrupt flag is set on the current thread so that any outer code is able to see the interrupt and react appropriately, e.g. instead of printing done, the thread running PeriodicTask may have checked the interrupt status of itself and done something interesting.
If your goal is to stop the thread itself, then you may want to have PeriodicTask extend Thread, which is not recommended unless you have a good reason to do so, or, have PeriodicTask implement Runnable. Consider the next example:
public class ThreadStopExample2 {
public static void main ( String[] args ) throws InterruptedException {
final PeriodicTask task = new PeriodicTask ();
Thread t = new Thread ( task );
t.start ();
Thread.sleep ( 12000 );
task.setInterval ( 1 );
Thread.sleep ( 3000 );
t.interrupt ();
}
static class PeriodicTask implements Runnable {
private volatile int interval = 5;
#Override
public void run () {
while ( true ) {
doSomething ();
try {
int count = 0;
while ( count++ < interval ) {
Thread.sleep ( 1000 );
}
} catch ( InterruptedException e ) {
Thread.currentThread ().interrupt ();
break;
}
}
}
public void setInterval ( int newInterval ) {
interval = newInterval;
}
private void doSomething () {
System.out.println ( "[" + Thread.currentThread ().getName ()
+ "] Interval: " + interval );
}
}
}
Here, PeriodicTask sits in a busy loop until the thread running it is interrupted. The interrupt is used to signal the PeriodicTask to exit the loop, which then allows the thread to complete by falling through the end of the run method.
Regarding your two explicit questions: no, I don't see any real problem with using PeriodicTask the way you are if you aren't intending to control the executing thread, e.g. maybe the instance of PeriodicTask is run by a thread in a pool (but do be sure to fix your code to be correctly synchronized), and, when using interrupt you call it on the instance of the thread that you want to interrupt. How you get a reference to that thread is dependent on your system.
You call interrupt() on the thread that's sleeping and it will throw an InterruptedException which you handle in your catch block. Then you have your new interval and you can loop around and go back to sleep. If you catch and handle the InterruptedException nothing further happens.
Let me provide a couple of links of examples of creating and interrupting threads, as from your comments you seem to be missing some important ideas. Please review these carefully and then you should understand the standard way to do what you are asking for.
http://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html
http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

How to wait for a number of threads to complete?

What is a way to simply wait for all threaded process to finish? For example, let's say I have:
public class DoSomethingInAThread implements Runnable{
public static void main(String[] args) {
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread());
t.start();
}
// wait for all threads' run() methods to complete before continuing
}
public void run() {
// do something here
}
}
How do I alter this so the main() method pauses at the comment until all threads' run() methods exit? Thanks!
You put all threads in an array, start them all, and then have a loop
for(i = 0; i < threads.length; i++)
threads[i].join();
Each join will block until the respective thread has completed. Threads may complete in a different order than you joining them, but that's not a problem: when the loop exits, all threads are completed.
One way would be to make a List of Threads, create and launch each thread, while adding it to the list. Once everything is launched, loop back through the list and call join() on each one. It doesn't matter what order the threads finish executing in, all you need to know is that by the time that second loop finishes executing, every thread will have completed.
A better approach is to use an ExecutorService and its associated methods:
List<Callable> callables = ... // assemble list of Callables here
// Like Runnable but can return a value
ExecutorService execSvc = Executors.newCachedThreadPool();
List<Future<?>> results = execSvc.invokeAll(callables);
// Note: You may not care about the return values, in which case don't
// bother saving them
Using an ExecutorService (and all of the new stuff from Java 5's concurrency utilities) is incredibly flexible, and the above example barely even scratches the surface.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class DoSomethingInAThread implements Runnable
{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
//limit the number of actual threads
int poolSize = 10;
ExecutorService service = Executors.newFixedThreadPool(poolSize);
List<Future<Runnable>> futures = new ArrayList<Future<Runnable>>();
for (int n = 0; n < 1000; n++)
{
Future f = service.submit(new DoSomethingInAThread());
futures.add(f);
}
// wait for all tasks to complete before continuing
for (Future<Runnable> f : futures)
{
f.get();
}
//shut down the executor service so that this thread can exit
service.shutdownNow();
}
public void run()
{
// do something here
}
}
instead of join(), which is an old API, you can use CountDownLatch. I have modified your code as below to fulfil your requirement.
import java.util.concurrent.*;
class DoSomethingInAThread implements Runnable{
CountDownLatch latch;
public DoSomethingInAThread(CountDownLatch latch){
this.latch = latch;
}
public void run() {
try{
System.out.println("Do some thing");
latch.countDown();
}catch(Exception err){
err.printStackTrace();
}
}
}
public class CountDownLatchDemo {
public static void main(String[] args) {
try{
CountDownLatch latch = new CountDownLatch(1000);
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread(latch));
t.start();
}
latch.await();
System.out.println("In Main thread after completion of 1000 threads");
}catch(Exception err){
err.printStackTrace();
}
}
}
Explanation:
CountDownLatch has been initialized with given count 1000 as per your requirement.
Each worker thread DoSomethingInAThread will decrement the CountDownLatch, which has been passed in constructor.
Main thread CountDownLatchDemo await() till the count has become zero. Once the count has become zero, you will get below line in output.
In Main thread after completion of 1000 threads
More info from oracle documentation page
public void await()
throws InterruptedException
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
Refer to related SE question for other options:
wait until all threads finish their work in java
Avoid the Thread class altogether and instead use the higher abstractions provided in java.util.concurrent
The ExecutorService class provides the method invokeAll that seems to do just what you want.
Consider using java.util.concurrent.CountDownLatch. Examples in javadocs
Depending on your needs, you may also want to check out the classes CountDownLatch and CyclicBarrier in the java.util.concurrent package. They can be useful if you want your threads to wait for each other, or if you want more fine-grained control over the way your threads execute (e.g., waiting in their internal execution for another thread to set some state). You could also use a CountDownLatch to signal all of your threads to start at the same time, instead of starting them one by one as you iterate through your loop. The standard API docs have an example of this, plus using another CountDownLatch to wait for all threads to complete their execution.
As Martin K suggested java.util.concurrent.CountDownLatch seems to be a better solution for this. Just adding an example for the same
public class CountDownLatchDemo
{
public static void main (String[] args)
{
int noOfThreads = 5;
// Declare the count down latch based on the number of threads you need
// to wait on
final CountDownLatch executionCompleted = new CountDownLatch(noOfThreads);
for (int i = 0; i < noOfThreads; i++)
{
new Thread()
{
#Override
public void run ()
{
System.out.println("I am executed by :" + Thread.currentThread().getName());
try
{
// Dummy sleep
Thread.sleep(3000);
// One thread has completed its job
executionCompleted.countDown();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
try
{
// Wait till the count down latch opens.In the given case till five
// times countDown method is invoked
executionCompleted.await();
System.out.println("All over");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
If you make a list of the threads, you can loop through them and .join() against each, and your loop will finish when all the threads have. I haven't tried it though.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join()
Create the thread object inside the first for loop.
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
// some code to run in parallel
}
});
threads[i].start();
}
And then so what everyone here is saying.
for(i = 0; i < threads.length; i++)
threads[i].join();
You can do it with the Object "ThreadGroup" and its parameter activeCount:
As an alternative to CountDownLatch you can also use CyclicBarrier e.g.
public class ThreadWaitEx {
static CyclicBarrier barrier = new CyclicBarrier(100, new Runnable(){
public void run(){
System.out.println("clean up job after all tasks are done.");
}
});
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
Thread t = new Thread(new MyCallable(barrier));
t.start();
}
}
}
class MyCallable implements Runnable{
private CyclicBarrier b = null;
public MyCallable(CyclicBarrier b){
this.b = b;
}
#Override
public void run(){
try {
//do something
System.out.println(Thread.currentThread().getName()+" is waiting for barrier after completing his job.");
b.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
To use CyclicBarrier in this case barrier.await() should be the last statement i.e. when your thread is done with its job. CyclicBarrier can be used again with its reset() method. To quote javadocs:
A CyclicBarrier supports an optional Runnable command that is run once per barrier point, after the last thread in the party arrives, but before any threads are released. This barrier action is useful for updating shared-state before any of the parties continue.
The join() was not helpful to me. see this sample in Kotlin:
val timeInMillis = System.currentTimeMillis()
ThreadUtils.startNewThread(Runnable {
for (i in 1..5) {
val t = Thread(Runnable {
Thread.sleep(50)
var a = i
kotlin.io.println(Thread.currentThread().name + "|" + "a=$a")
Thread.sleep(200)
for (j in 1..5) {
a *= j
Thread.sleep(100)
kotlin.io.println(Thread.currentThread().name + "|" + "$a*$j=$a")
}
kotlin.io.println(Thread.currentThread().name + "|TaskDurationInMillis = " + (System.currentTimeMillis() - timeInMillis))
})
t.start()
}
})
The result:
Thread-5|a=5
Thread-1|a=1
Thread-3|a=3
Thread-2|a=2
Thread-4|a=4
Thread-2|2*1=2
Thread-3|3*1=3
Thread-1|1*1=1
Thread-5|5*1=5
Thread-4|4*1=4
Thread-1|2*2=2
Thread-5|10*2=10
Thread-3|6*2=6
Thread-4|8*2=8
Thread-2|4*2=4
Thread-3|18*3=18
Thread-1|6*3=6
Thread-5|30*3=30
Thread-2|12*3=12
Thread-4|24*3=24
Thread-4|96*4=96
Thread-2|48*4=48
Thread-5|120*4=120
Thread-1|24*4=24
Thread-3|72*4=72
Thread-5|600*5=600
Thread-4|480*5=480
Thread-3|360*5=360
Thread-1|120*5=120
Thread-2|240*5=240
Thread-1|TaskDurationInMillis = 765
Thread-3|TaskDurationInMillis = 765
Thread-4|TaskDurationInMillis = 765
Thread-5|TaskDurationInMillis = 765
Thread-2|TaskDurationInMillis = 765
Now let me use the join() for threads:
val timeInMillis = System.currentTimeMillis()
ThreadUtils.startNewThread(Runnable {
for (i in 1..5) {
val t = Thread(Runnable {
Thread.sleep(50)
var a = i
kotlin.io.println(Thread.currentThread().name + "|" + "a=$a")
Thread.sleep(200)
for (j in 1..5) {
a *= j
Thread.sleep(100)
kotlin.io.println(Thread.currentThread().name + "|" + "$a*$j=$a")
}
kotlin.io.println(Thread.currentThread().name + "|TaskDurationInMillis = " + (System.currentTimeMillis() - timeInMillis))
})
t.start()
t.join()
}
})
And the result:
Thread-1|a=1
Thread-1|1*1=1
Thread-1|2*2=2
Thread-1|6*3=6
Thread-1|24*4=24
Thread-1|120*5=120
Thread-1|TaskDurationInMillis = 815
Thread-2|a=2
Thread-2|2*1=2
Thread-2|4*2=4
Thread-2|12*3=12
Thread-2|48*4=48
Thread-2|240*5=240
Thread-2|TaskDurationInMillis = 1568
Thread-3|a=3
Thread-3|3*1=3
Thread-3|6*2=6
Thread-3|18*3=18
Thread-3|72*4=72
Thread-3|360*5=360
Thread-3|TaskDurationInMillis = 2323
Thread-4|a=4
Thread-4|4*1=4
Thread-4|8*2=8
Thread-4|24*3=24
Thread-4|96*4=96
Thread-4|480*5=480
Thread-4|TaskDurationInMillis = 3078
Thread-5|a=5
Thread-5|5*1=5
Thread-5|10*2=10
Thread-5|30*3=30
Thread-5|120*4=120
Thread-5|600*5=600
Thread-5|TaskDurationInMillis = 3833
As it's clear when we use the join:
The threads are running sequentially.
The first sample takes 765 Milliseconds while the second sample takes 3833 Milliseconds.
Our solution to prevent blocking other threads was creating an ArrayList:
val threads = ArrayList<Thread>()
Now when we want to start a new thread we most add it to the ArrayList:
addThreadToArray(
ThreadUtils.startNewThread(Runnable {
...
})
)
The addThreadToArray function:
#Synchronized
fun addThreadToArray(th: Thread) {
threads.add(th)
}
The startNewThread funstion:
fun startNewThread(runnable: Runnable) : Thread {
val th = Thread(runnable)
th.isDaemon = false
th.priority = Thread.MAX_PRIORITY
th.start()
return th
}
Check the completion of the threads as below everywhere it's needed:
val notAliveThreads = ArrayList<Thread>()
for (t in threads)
if (!t.isAlive)
notAliveThreads.add(t)
threads.removeAll(notAliveThreads)
if (threads.size == 0){
// The size is 0 -> there is no alive threads.
}
The problem with:
for(i = 0; i < threads.length; i++)
threads[i].join();
...is, that threads[i + 1] never can join before threads[i].
Except the "latch"ed ones, all solutions have this lack.
No one here (yet) mentioned ExecutorCompletionService, it allows to join threads/tasks according to their completion order:
public class ExecutorCompletionService<V>
extends Object
implements CompletionService<V>
A CompletionService that uses a supplied Executor to execute tasks. This class arranges that submitted tasks are, upon completion, placed on a queue accessible using take. The class is lightweight enough to be suitable for transient use when processing groups of tasks.
Usage Examples.
Suppose you have a set of solvers for a certain problem, each returning a value of some type Result, and would like to run them concurrently, processing the results of each of them that return a non-null value, in some method use(Result r). You could write this as:
void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException, ExecutionException {
CompletionService<Result> cs = new ExecutorCompletionService<>(e);
solvers.forEach(cs::submit);
for (int i = solvers.size(); i > 0; i--) {
Result r = cs.take().get();
if (r != null)
use(r);
}
}
Suppose instead that you would like to use the first non-null result of the set of tasks, ignoring any that encounter exceptions, and cancelling all other tasks when the first one is ready:
void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException {
CompletionService<Result> cs = new ExecutorCompletionService<>(e);
int n = solvers.size();
List<Future<Result>> futures = new ArrayList<>(n);
Result result = null;
try {
solvers.forEach(solver -> futures.add(cs.submit(solver)));
for (int i = n; i > 0; i--) {
try {
Result r = cs.take().get();
if (r != null) {
result = r;
break;
}
} catch (ExecutionException ignore) {}
}
} finally {
futures.forEach(future -> future.cancel(true));
}
if (result != null)
use(result);
}
Since: 1.5 (!)
Assuming use(r) (of Example 1) also asynchronous, we had a big advantage. #

Categories

Resources