多线程中 CountDownLatch CyclicBarrier Semaphore的使用

  CountDownLatch 调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行。也可以传入时间,表示时间到之后,count还没有为0的时候,就会继续执行。

package ch.test.notes.thread;

import java.util.concurrent.CountDownLatch;

/**
 * Description: CountDownLatch 的使用
 *
 * @author cy
 * @date 2018年10月16日 10:52
 * version 1.0
 */
public class MyThreadCountDownLatch  {

    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(2);

        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("线程"+Thread.currentThread().getName()+"正在执行任务");
                    Thread.sleep(3000);
                    System.out.println("线程"+Thread.currentThread().getName()+"结束执行任务");
                    countDownLatch.countDown();
                }catch (Exception e){

                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("线程"+Thread.currentThread().getName()+"正在执行任务");
                    Thread.sleep(15000);
                    System.out.println("线程"+Thread.currentThread().getName()+"结束执行任务");
                    countDownLatch.countDown();
                }catch (Exception e){

                }
            }
        }.start();
        try {
            System.out.println("等待线程执行完毕");
            countDownLatch.await();
            System.out.println("线程执行完毕,继续执行主程序");
        }catch (Exception e){

        }


    }
}

CyclicBarrier 是多个线程中,等待其他线程执行完之后,线程中才继续执行。

package ch.test.notes.thread;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * Description: CyclicBarrier 的使用
 *
 * @author cy
 * @date 2018年10月16日 10:52
 * version 1.0
 */
public class MyThreadCyclicBarrier {

    public static void main(String[] args) {
        int n = 4;
        CyclicBarrier barrier  = new CyclicBarrier(n);
        for(int i=0;i<n;i++) {
            new Writer(barrier).start();
        }
    }
    static class Writer extends Thread{
        private CyclicBarrier cyclicBarrier;
        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
            try {
                Thread.sleep(5000);      //以睡眠来模拟写入数据操作
                System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
            System.out.println("所有线程写入完毕,继续处理其他任务...");
        }
    }
}

Semaphore  可以控制同时访问的个数(8个工人竞争5个机器,没有顺序)

package ch.test.notes.thread;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

/**
 * Description: Semaphore 的使用
 *
 * @author cy
 * @date 2018年10月16日 10:52
 * version 1.0
 */
public class MyThreadSemaphore {

    public static void main(String[] args) {
        int N = 8;            //工人数
        Semaphore semaphore = new Semaphore(5); //机器数目
        for(int i=0;i<N;i++) {
            new Worker(i, semaphore).start();
        }
    }

    static class Worker extends Thread{
        private int num;
        private Semaphore semaphore;
        public Worker(int num,Semaphore semaphore){
            this.num = num;
            this.semaphore = semaphore;
        }

        @Override
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("工人"+this.num+"占用一个机器在生产...");
                Thread.sleep(2000);
                System.out.println("工人"+this.num+"释放出机器");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

   1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

    CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

    而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

    另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

    2)Semaphore其实和锁有点类似,就是几个人同时竞争一个某些资源,但是一个资源同时只能有一个。

原文地址:https://www.cnblogs.com/chengyangyang/p/10836976.html