前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CountDownLatch、CyclicBarrier和Semaphore使用

CountDownLatch、CyclicBarrier和Semaphore使用

作者头像
GreizLiao
发布2019-09-23 15:25:01
2870
发布2019-09-23 15:25:01
举报
文章被收录于专栏:足球是圆的足球是圆的
  • CountDownLatch

CountDownLatch是用来线程计数的。等待一组线程全部执行完后再本线程继续执行。如:A线程需要等待B、C和D(由初始化CountDownLatch参数觉得等待多少个线程)线程执行完后再执行。

主要的方法:

代码语言:javascript
复制
// 构造方法,count决定等待多少个线程
public CountDownLatch(int count)
// 等待线程完成数减1
public void countDown()
// 调用await本线程会挂起,当等待线程未完成数为0,即countDown调用次数等于构造方法参数值时会被唤醒
public void await()
public boolean await(long timeout, TimeUnit unit)

以下是CountDownLatch的用法:

代码语言:javascript
复制
public class CountDownLatchTest {
    public static void main(String[] args) {
        final CountDownLatch countDownLatch = new CountDownLatch(2);
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                try {
                    String name = Thread.currentThread().getName();
                    System.out.println("子线程" + name + "正在运行中......");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("子线程" + name + "执行完毕");
                    countDownLatch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }

        try {
            System.out.println("======等待两个子线程执行完毕");
            // 只有子线程执行完毕个数等于CountDownLatch初始化个数才会继续执行await后面代码
            countDownLatch.await();
            System.out.println("两个子线程都执行完毕!!!!!!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("主线程继续执行中。。。。。。。。");
    }
}

结果:

代码语言:javascript
复制
子线程Thread-0正在运行中......
======等待两个子线程执行完毕
子线程Thread-1正在运行中......
子线程Thread-1执行完毕
子线程Thread-0执行完毕
两个子线程都执行完毕!!!!!!
主线程继续执行中。。。。。。。。
  • CyclicBarrier

CyclicBarrier 设置一个障碍点,让同组线程到达改点的线程等待本组未达到该点的线程,同组全部线程到达该点才越过障碍物释放资源,让其它组循环利用该对象。

主要方法:

代码语言:javascript
复制
// 构造方法设置同组线程数
public CyclicBarrier(int parties)
// 构造方法设置同组线程数;全部达到障碍物时执行barrierAction函数
public CyclicBarrier(int parties, Runnable barrierAction)
// 某个线程调用await时挂起,需要等同组所有线程到达才能唤醒
public int await() throws InterruptedException, BrokenBarrierException

以下是 CyclicBarrier 的用法:

代码语言:javascript
复制
/**
 * Created on 18/3/15 14:40.
 *
 * @author wolf
 */
public class CyclicBarrierTest {
    public static void main(String[] args) {
        int n = 3;
        CyclicBarrier barrier = new CyclicBarrier(n);
        for (int i = 0; i < 3; i++) {
            new Worker(barrier).start();
        }

        try {
            TimeUnit.SECONDS.sleep(6);
            System.out.println("--------讨厌的循环利用分割线------------");
        } catch (Exception e) {
            e.printStackTrace();
        }

        for (int i = 0; i < n; i++) {
            new Worker(barrier).start();
        }
    }

    static class Worker extends Thread {
        private CyclicBarrier barrier;
        public Worker(CyclicBarrier barrier) {
            this.barrier = barrier;
        }
        @Override
        public void run() {
            long startTime = System.currentTimeMillis();
            String name = Thread.currentThread().getName();
            System.out.println("线程 " + name + " 正在执行任务.......");
            try {
                int time = RandomUtils.nextInt(1, 5);
                TimeUnit.SECONDS.sleep(time);
                System.out.println("线程 " + name + " 执行任务完毕!!!用时:" + time);
                barrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("线程 " + name + " 全部耗时:"+(System.currentTimeMillis()-startTime));
        }
    }
}
  • Semaphore

Semaphore 通过名字我们就知道这个计算信号量,也就是控制获取资源的许可证。

主要的方法:

代码语言:javascript
复制
// 构造方法设置可用资源的数量,即许可证的数量
public Semaphore(int permits)
// 构造方法设置可用资源的数量,即许可证的数量,fair 是否公平获得许可证,默认是先来后到公平的
public Semaphore(int permits, boolean fair)
// 同步获取许可证,
public void acquire() throws InterruptedException
// 尝试获取许可证,结果直接返回
public boolean tryAcquire()
// 尝试获取许可证,结果等待时间超时直接返回
public boolean tryAcquire(long timeout, TimeUnit unit)
// 释放许可证,可给其它等待线程使用
public void release()

以下是 Semaphore 用法:

代码语言:javascript
复制
public class SemaphoreTest {
    public static void main(String[] args) {
        int no = 5;
        Semaphore semaphore = new Semaphore(2);
        for (int i = 0; i < no; i++) {
            new Worker(i, semaphore).start();
        }
    }
    static class Worker extends Thread {
        private int no;
        private Semaphore semaphore;
        public Worker(int no, Semaphore semaphore) {
            this.no = no;
            this.semaphore = semaphore;
        }
        @Override
        public void run() {
            try {
                long startTime = System.currentTimeMillis();
                semaphore.acquire();
                System.out.println("worker " + this.no + " 获取许可证,开始工作....");
                int time = RandomUtils.nextInt(1, 5);
                TimeUnit.SECONDS.sleep(time);
                semaphore.release();
                System.out.println("worker " + this.no + " 完成工作,释放许可证!耗时:" + (System.currentTimeMillis() - startTime));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档