Waiting for threads

I have a method that contains the following (Java) code:

doSomeThings(); doSomeOtherThings(); 

doSomeThings() creates some threads, each of which will work only for a finite time. The problem is that I do not want doSomeOtherThings() called until all threads started with doSomeThings() are complete. (Also, doSomeThings() will call methods that can start new threads, etc. I do not want to do doSomeOtherThings() until all these threads have finished.)

This is because doSomeThings() , by the way, sets myObject to null , and doSomeOtherThings() calls myObject.myMethod() , and I don't want myObject be null at this time.

Is there any standard way to do such things (in Java)?

+4
source share
6 answers

You might want to check out the java.util.concurrent package. In particular, you can use CountDownLatch as in

 package de.grimm.game.ui; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) throws Exception { final ExecutorService executor = Executors.newFixedThreadPool(5); final CountDownLatch latch = new CountDownLatch(3); for( int k = 0; k < 3; ++k ) { executor.submit(new Runnable() { public void run() { // ... lengthy computation... latch.countDown(); } }); } latch.await(); // ... reached only after all threads spawned have // finished and acknowledged so by counting down the // latch. System.out.println("Done"); } } 

Obviously, this method will work only if you know the number of branched threads in advance, since you need to initialize the latch with this number.

Another way is to use condition variables, for example:

 boolean done = false; void functionRunInThreadA() { synchronized( commonLock ) { while( !done ) commonLock.wait(); } // Here it is safe to set the variable to null } void functionRunInThreadB() { // Do something... synchronized( commonLock ) { done = true; commonLock.notifyAll(); } } 

You may need to add exception handling ( InteruptedException ) and some of them.

+10
source

Take a look at the Thread.join() method.

I do not understand your exact implementation, but it seems that doSomeThings () should wait for child threads before returning.

Inside the doSomeThings () method, wait in threads by calling Thread.join ().

When you create a thread and call this join join () method, the calling thread waits until this thread object dies.

Example:

 // Create an instance of my custom thread class MyThread myThread = new MyThread(); // Tell the custom thread object to run myThread.start(); // Wait for the custom thread object to finish myThread.join(); 
+6
source

You are looking for an executive service and using futures :)

See http://java.sun.com/docs/books/tutorial/essential/concurrency/exinter.html

So basically collect the futures for all the executables you send to the executing service. Copy all futures and call the get () methods. They will return when the corresponding runnable is executed.

+3
source

Another useful, more robust Encryption Barrier that you can use will perform similar functions like the CountdownLatch CyclicBarrier . It works similarly to CountdownLatch, where you need to know how many batches (streams) are used, but it allows you to reuse the barrier, as each time added to creating a new instance of CountdownLatch.

I like the suggestion that I use ExecutorService, collecting futures and calls, type everything until they end.

+1
source

Another option is a sleeping main thread, and let it check everything so often if the rest of the threads are completed. However, I like the answers of Dirk and Marcus Adams - just throw it away for the sake of completeness.

0
source

Depending on what exactly you are trying to do here. Your main problem is the ability to dynamically determine the various threads that are generated by the sequential methods called from doSomeThings() , and then be able to wait for them to complete before calling doSomeOtherThings() ? Or can you recognize the threads that spawn during compilation? In the later case, there are many solutions, but all of them are mainly associated with calling the Thread.join() method for all these threads from any place where they are created.

If this is really the first, then you better use ThreadGroup and its enumerate() method. This gives you an array of all threads created by doSomeThings () if you correctly added new threads to ThreadGroup. You can then skip all the stream references in the returned array and call join() in the main stream just before you call doSomeOtherThings() .

0
source

Source: https://habr.com/ru/post/1306047/


All Articles