Wait for the child thread to finish

join future CountDownLanch CyclicBarrier
future scenario:
If it is a multi-threaded cooperative program, such as the Fibonacci sequence, 1, 1, 2, 3, 5, 8... use multi-threading to calculate.
But the latter needs the result of the former, so it needs to use the callable interface.
The usage of callable is the same as that of runnable, except that it calls the call method, which has a generic return value type that you can specify arbitrarily.

Threads belong to the asynchronous computing model, so you can't get function return values ​​directly from other threads.
At this time, Future came out. Futrue can monitor the situation where the target thread calls call. When you call the get() method of Future to get the result, the current thread starts to block, and the call method ends and returns the result directly.

public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        List<Future> fsL = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            int finalI = i;
            Future f = es.submit(new Callable() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("The child thread is calculating");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace ();
                    }
                    int sum = 0;
                        sum + = finalI;
                    return sum;
                }
            });
            fsL.add(f);
        }
        for (Future fu : fsL) {
            try {
                System.out.println("Thread result="+fu.get());
            } catch (InterruptedException e) {
                e.printStackTrace ();
            } catch (ExecutionException e) {
                e.printStackTrace ();
            }
        }
    }


CountDownLanch scene
from: http://www.linzenews.com/develop/2002.html

A synchronization helper class that allows one or more threads to wait until a set of operations being performed in other threads are completed.
Initializes CountDownLatch with the given count. Since the countDown() method is called, the await method will block until the current count reaches zero. After that, all waiting threads are released and all subsequent calls to await return immediately. This happens only once - the count cannot be reset. If you need to reset the count, consider using a CyclicBarrier.
CountDownLatch is a generic synchronization tool that has many uses. A CountDownLatch initialized with a count of 1 is used as a simple on/off latch, or entry: all threads calling await wait at the entry until the entry is opened by the thread calling countDown(). A CountDownLatch initialized with N can cause a thread to wait until N threads complete an operation, or to wait until an operation completes N times.
A useful feature of CountDownLatch is that it does not require the thread calling the countDown method to wait until the count reaches zero before continuing, but it simply prevents any thread from continuing through an await until all threads have passed.

For example: For example, a group of us (multiple threads) want to travel from Beijing to Guangzhou together. We agree that everyone will arrive at the Beijing West Railway Station. When the last person arrives at the Beijing West Railway Station (the counter is 0), we will The following operations will be performed simultaneously.
countdownLanch Scenario 1:
Example usage: Two classes are given below, where a set of worker threads use two countdown latches:
The first class is a start signal that prevents all workers from continuing until the driver is ready to continue.
The second class is a completion signal, which allows the driver to wait until all workers are finished.
class Driver { // ...
    void main() throws InterruptedException {
      CountDownLatch startSignal = new CountDownLatch(1);
      CountDownLatch doneSignal = new CountDownLatch(N);
 
      for (int i = 0; i < N; ++i) // create and start threads
        new Thread(new Worker(startSignal, doneSignal)).start();
 
      doSomethingElse();            // don't let run yet
      startSignal.countDown();      // let all threads proceed
      doSomethingElse();
      doneSignal.await();           // wait for all to finish
    }
  }
 
  class Worker implements Runnable {
    private final CountDownLatch startSignal;
    private final CountDownLatch doneSignal;
    Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
       this.startSignal = startSignal;
       this.doneSignal = doneSignal;
    }
    public void run() {
       try {
         startSignal.await();
         doWork();
         doneSignal.countDown();
 } catch (InterruptedException ex) {} // return;
    }
 
    void doWork() { ... }
  }

countdownLanch Scenario 2:
Another typical use is to divide a problem into N parts, describe each part with a Runnable that executes each part and counts down the latch, and then adds all Runnables to the Executor queue. When all subsections are complete, the coordinating thread can pass await. (A CyclicBarrier can be used instead when a thread must count down repeatedly this way.)
class Driver2 { // ...
   void main() throws InterruptedException {
     CountDownLatch doneSignal = new CountDownLatch(N);
     Executor and = ...

     for (int i = 0; i < N; ++i) // create and start threads
       e.execute(new WorkerRunnable(doneSignal, i));

     doneSignal.await();           // wait for all to finish
   }
 }

 class WorkerRunnable implements Runnable {
   private final CountDownLatch doneSignal;
   private final int i;
   WorkerRunnable(CountDownLatch doneSignal, int i) {
      this.doneSignal = doneSignal;
      this.i = i;
   }
   public void run() {
      try {
        doWork(i);
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

Memory consistency effect: the operation happen-before in a thread calling countDown() is immediately followed by the operation that returns successfully from the corresponding await() in another thread.
CyclicBarrier scene
from: http://blog.csdn.net/shihuacai/article/details/8856407A
synchronization helper class that allows a group of threads to wait for each other until a common barrier point is reached. CyclicBarrier is useful in programs involving a set of fixed-size threads that must wait for each other from time to time. Because the barrier can be reused after releasing the waiting thread, it is called a cyclic barrier.

The main task is executed only when all sub-tasks are completed. At this time, you can choose to use CyclicBarrier.


public class CyclicBarrierTest {

	public static void main(String[] args) throws IOException, InterruptedException {
		//If the parameter is changed to 4, but only 3 players are added below, this will wait forever
		//Waits until all parties have invoked await on this barrier.
		CyclicBarrier barrier = new CyclicBarrier(3);

		ExecutorService executor = Executors.newFixedThreadPool(3);
		executor.submit(new Thread(new Runner(barrier, "1号选手")));
		executor.submit(new Thread(new Runner(barrier, "2号选手")));
		executor.submit(new Thread(new Runner(barrier, "3号选手")));

		executor.shutdown();
	}
}

class Runner implements Runnable {
	// A synchronization helper class that allows a group of threads to wait on each other until some common barrier point is reached
	private CyclicBarrier barrier;

	private String name;

	public Runner(CyclicBarrier barrier, String name) {
		super();
		this.barrier = barrier;
		this.name = name;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(1000 * (new Random()).nextInt(8));
			System.out.println(name + "Ready...");
			// The await method of the barrier will wait until all participants have called the await method on this barrier.
			barrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace ();
		} catch (BrokenBarrierException e) {
			e.printStackTrace ();
		}
		System.out.println(name + " 起跑!");
	}
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326668061&siteId=291194637