[Concurrent] multi-threading and Java Concurrency Tools

There are two types of
① concurrent processes control Related: CountDownLatch, CyclicBarrier, Semaphore
between ② thread exchange data relating to: Exchanger;


CountDownLatch

  • Action: allowing one or more threads waiting for other threads to finish
  • Use steps:
    ① a definition of a CountDownLatch (called counter), and waits for the specified number of times;
    ② the right time in the counter is decremented. 1;
    ③ the need to wait for the end positions of all tasks, the await call () method;

According to two examples in the JDK documentation finishing:
Example 1:

public class CountDownLatchLearning {

    public void doSomething() { CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(10); //创建并启动线程 for (int i = 0; i < 10; ++i) { new Thread(new Worker(startSignal, doneSignal)).start(); } doSomeThingBeforeAllThreadsProcess(); startSignal.countDown(); //让之前for循环创建的线程开始真正工作 try { doneSignal.await(); // 等待之前for循环创建的线程执行结束 } catch (InterruptedException e) { e.printStackTrace(); } doSomeThingAfterAllThreadsProcess(); } private void doSomeThingAfterAllThreadsProcess() { //所有任务开始前,做一些准备工作 } private void doSomeThingBeforeAllThreadsProcess() { //所有任务开始后,做一些其他工作,如合并结果等等 } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } @Override public void run() { try { startSignal.await();//等待,开始信号为0再继续向下进行 doWork(); } catch (InterruptedException ex) { ex.printStackTrace(); }finally { doneSignal.countDown();//完成后,将结束信号减1 } } void doWork() { //这里是真正有意义的任务 } } } 

Example 2:

public class CountDownLatchLearning1 {

    public void doSomething() { CountDownLatch doneSignal = new CountDownLatch(100); Executor e = Executors.newFixedThreadPool(10); for (int i = 0; i < 100; ++i) { e.execute(new WorkerRunnable(doneSignal, i)); } try { doneSignal.await(); // 等待所有任务结束 } catch (InterruptedException e1) { e1.printStackTrace(); } } private void doSomeThingAfterAllThreadsProcess() { //所有任务开始前,做一些准备工作 } private void doSomeThingBeforeAllThreadsProcess() { //所有任务开始后,做一些其他工作,如合并结果等等 } class WorkerRunnable implements Runnable { private final CountDownLatch doneSignal; private final int i; WorkerRunnable(CountDownLatch doneSignal, int i) { this.doneSignal = doneSignal; this.i = i; } @Override public void run() { doWork(i); doneSignal.countDown(); } void doWork(int i) { //这里是真正的有意义的任务 } } } 

CyclicBarrier

  • Role: then let a group of threads waiting to execute certain state and then all simultaneously for multi-threaded computing data, the combined results of the last scene.
  • use:
①构造:
public CyclicBarrier(int parties, Runnable barrierAction) {} public CyclicBarrier(int parties) {} 其中: parties指让多少个线程或者任务等待至barrier状态; barrierAction指当这些线程都达到barrier状态时会执行的内容; ②在合适的时机调用await方法,告诉CyclicBarrier我(当前线程)已经达到了屏障,然后当前线程被阻塞 public int await(); public int await(long timeout, TimeUnit unit); 返回当前线程到达屏障的次序( 0 ~ getParties() - 1) ③其他有用的方法 getNumberWaiting():获取CyclicBarrier阻塞的线程数量 isBroken():阻塞线程(一个或多个)是否被中断 reset():重置CyclicBarrier 

for example:

public class CyclicBarriarExapmle {

    private Map<String, Integer> map = new ConcurrentHashMap<>(); CyclicBarrier barrier = new CyclicBarrier(10, ()->{ //线程全部到达屏障后,执行的任务 System.out.println("我是线程全部到达屏障后,执行的任务"); int result = 0; for(Map.Entry<String, Integer> entry : map.entrySet()){ result += entry.getValue(); } System.out.println("最终计算结果:" + result); }); private void calculate(){ for(int i = 0; i < 10; i++){ final int j = i; new Thread(()->{ //执行计算,假如计算结果是,计算完成后,放入map中 System.out.println("当前计算结果:" + j); map.put(Thread.currentThread().getName(), j); try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } public static void main(String[] args){ CyclicBarriarExapmle exapmle = new CyclicBarriarExapmle(); exapmle.calculate(); } } 

The final output of the program:

当前计算结果:1
当前计算结果:4
当前计算结果:3
当前计算结果:2
当前计算结果:6
当前计算结果:0
当前计算结果:7
当前计算结果:5
当前计算结果:8
当前计算结果:9
我是线程全部到达屏障后,执行的任务
最终计算结果:45

CountDownLatch and CyclicBarrier the difference : both can be used to make a set of threads waiting for other threads, but CyclicBarrier more powerful, reusable, and can set priorities.


Semaphore

  • Role: control the number of threads simultaneously access a particular resource, flow control
  • Use: ① create Semaphore, according to resource characteristics, specify the number of threads can access the resource at the same time; ② when the specific use of resources, first obtain a license from Semaphore, used up resources after the release of resources
  • It is worth noting: Before a thread release, does not have to acquire. The procedure may be necessary to control their own.
/**
     * Releases a permit, returning it to the semaphore.
     *
     * <p>Releases a permit, increasing the number of available permits by
     * one.  If any threads are trying to acquire a permit, then one is
     * selected and given the permit that was just released.  That thread
     * is (re)enabled for thread scheduling purposes.
     *
     * <p>There is no requirement that a thread that releases a permit must
     * have acquired that permit by calling {@link #acquire}.
     * Correct usage of a semaphore is established by programming convention
     * in the application.
     */
    public void release() { sync.releaseShared(1); } 

for example:

public class SemaphoreExample {
    private Semaphore semaphore = new Semaphore(10); private Executor executor = Executors.newFixedThreadPool(30); public void calculate(){ for(int i = 0; i < 30; i++){ executor.execute(()->{ try { //获取许可证 semaphore.acquire(); //执行计算 System.out.println("使用资源,执行任务"); //释放许可证 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }); } } } 

Exchanger

  • Role: the exchange of data between threads, which provides a synchronization point, two threads can exchange data with each other, these two threads to exchange data exchange () method, if the first thread to execute the method, it would have been waiting for a second thread also performing the method, when two threads have reached the synchronization point, these two threads can exchange data.
public class ExchangerExample {

    public static void main(String[] args){ Exchanger<String> exchanger = new Exchanger<>(); new Thread(()->{ String resultOne = "A"; try { String exchangeResult = exchanger.exchange(resultOne); System.out.println("我的计算结果是:" + resultOne + ",与我交换数据的那个线程计算的结果是:" + exchangeResult); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(()->{ String resultTwo = "B"; try { String exchangeResult = exchanger.exchange(resultTwo); System.out.println("我的计算结果是:" + resultTwo + ",与我交换数据的那个线程计算的结果是:" + exchangeResult); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } } 

reference

"Java concurrent programming art", with appropriate changes

20,171,219 Updated: Increase the interpretation of the release of Semaphore method.



Author: maxwellyue
link: https: //www.jianshu.com/p/738d1ddd6731
Source: Jane book
Jane book copyright reserved by the authors, are reproduced in any form, please contact the author to obtain authorization and indicate the source.

Guess you like

Origin www.cnblogs.com/xiaoshen666/p/11258548.html