Java常用的并发工具类:CountDownLatch、CyclicBarrier、Semaphore、Exchanger

1、CountDownLatch 等待多线程完成

它的构造函数接收一个int参数作为计数器,想等待N个点,就传入N。

当调用CountDownLatch的countDown()方法时,N就会减1,直至减为0。

使用await()方法等待,当N的值变为0时,执行await的线程继续执行

2、CyclicBarrier 同步屏障(可以理解为可循环的屏障)

可循环使用的屏障,它要做的事情就是让一组线程到达屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会打开,所有被阻塞的线程才会继续执行

默认构造方法接收一个int参数,表示屏障拦截的线程数,每个线程调用await方法告诉CyclicBarrier 已经达到屏障了,然后当前线程阻塞

3、CountDownLatch   VS  CyclicBarrier 

CountDownLatch的计数器只使用一次,而CyclicBarrier 的计数器可以Reset方法重置,重复使用

4、Semaphore  控制线程并发数的信号量

控制有限个线程使用资源。构造方法接收一个int参数N,表示最大并发量,每个线程使用资源前调用acquire()方法获取权限,使用完后调用release()方法释放权限;

Semaphore有一个构造函数,可以传入一个int型整数n,表示某段代码最多只有n个线程可以访问,如果超出了n,那么请等待,等到某个线程执行完毕这段代码块,下一个线程再进入

5、Exchanger线程间的数据交换

提供一个同步点,在这个同步点,两个线程可以交换彼此的数据

1、public class CountDownLatchTest {

    static CountDownLatch c = new CountDownLatch(2);

    static ExecutorService pool = Executors.newFixedThreadPool(2);

    public static void main(String agrs[]){

      pool.execute(new Runnable() {

        public void run() {

          try {

            TimeUnit.MILLISECONDS.sleep(3);

          }catch (InterruptedException e){

            e.printStackTrace();

          }

          System.out.println("This is A");

          c.countDown();

        }

      });

      pool.execute(new Runnable() {

        public void run() {

          try {

            TimeUnit.MILLISECONDS.sleep(3);

          }catch (InterruptedException e){

            e.printStackTrace();

          }

          System.out.println("This is B");

          c.countDown();

        }

      });

      try {

        c.await();

      }catch (InterruptedException e){

      }

      System.out.println("This is main");

    }

}

2、public class CyclicBarrierTest{

  static CyclicBarrier c = new CyclicBarrier(2);

  static ExecutorService pool = Executors.newFixedThreadPool(2);

  public static void main(String)args){

    pool.execute(new Runnable(){

      public void run(){

        sysout("this is A");

        try{

          c.await();

          sysout("this is AA");

        }catch( Exception e){ e.printStackTrace();  }

      }

    }); 

    pool.execute(new Runnable(){

      public void run(){

        sysout("this is B");

        try{

          c.await();

          sysout("this is BB");

        }catch( Exception e){ e.printStackTrace();  }

      }

    });

   pool.shutdown();

  }

}

5、public  Class ExchangerTest{

  private static final Exchanger<String> exgr = new Exchanger<String>();

  private static ExecutorService pool= Executors.newFixedThreadPool(2);

  public  static void main(String[] args){

    pool.execute(new Runnable(){

      public void run(){

        String A = "银行流水A";

        try{ 

          A = exgr.exchange(A);

          sysout("A当前值:"+A);

         }catch(InterruptedException e){    }

      }

    });

    pool.execute(new Runnable(){

      public void run(){

        String B = "银行流水B";

        try{ 

          B = exgr.exchange(B);

          sysout(" B当前值:"+B);

         }catch(InterruptedException e){    }

      }

    });

    pool.shutdown();

  }

}

原文地址:https://www.cnblogs.com/blackdd/p/12522692.html