Java – observer mode with threads
I want to run several threads and join them at the end of my main method, so I can know when they are finished and process some information
I don't want to put my threads in an array and execute join () one by one, because join is a blocking method. I will wait for some threads that are still running in the main thread, while other threads may have completed and no one may know
I have considered the possibility of implementing an observer pattern for my thread: an interface with update () method, an abstract class extending from the thread (or implementing runnable), set and get methods for listeners, and a class that starts all threads
If my understanding is correct, the observer will not block a particular join () to get a thread Instead, it waits in some way until the thread calls the update () method to perform the operation In this case, update() should be called immediately after the thread completes
I have no idea how to achieve this I've tried a similar model, but I don't know how to use the observer / listener to wake up / block my main thread I have used this old post as a template: how to know if other threads have finished? But once the thread calls the update () method, I can't find a method to wake up my main method Only one observer object will be instantiated for all threads
Can you think of a way to use observer mode to wait for all threads to complete without blocking one main join () call after another? Any other suggestions to solve this problem will be appreciated Thank you in advance
Solution
I don't think you need observer mode The thread waiting for any result will have to be blocked, otherwise it will complete or loop infinity You can use some kind of BlockingQueue - the generator will add the calculation results to the blocking queue (and then complete), and the main thread will only receive these results without any results
Good news, it has implemented:) a good mechanism of completionservice and executors framework Try this:
private static final int NTHREADS = 5; private static final int NTASKS = 100; private static final ExecutorService exec = Executors.newFixedThreadPool(NTHREADS); public static void main(String[] args) throws InterruptedException { final CompletionService<Long> ecs = new ExecutorCompletionService<Long>(exec); for (final int i = 0; i < NTASKS ; ++i) { Callable<Long> task = new Callable<Long>() { @Override public Long call() throws Exception { return i; } }; ecs.submit(task); } for (int i = 0; i < NTASKS; ++i) { try { long l = ecs.take().get(); System.out.print(l); } catch (ExecutionException e) { e.getCause().printStackTrace(); } } exec.shutdownNow(); exec.awaitTermination(50,TimeUnit.MILLISECONDS); }