zoukankan      html  css  js  c++  java
  • CountDownLatch、CyclicBarrier和Semaphore使用

    • CountDownLatch

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

    主要的方法:

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

    以下是CountDownLatch的用法:

    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("主线程继续执行中。。。。。。。。");
        }
    }
    

    结果:

    子线程Thread-0正在运行中......
    ======等待两个子线程执行完毕
    子线程Thread-1正在运行中......
    子线程Thread-1执行完毕
    子线程Thread-0执行完毕
    两个子线程都执行完毕!!!!!!
    主线程继续执行中。。。。。。。。
    
    • CyclicBarrier

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

    主要方法:

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

    以下是 CyclicBarrier 的用法:

    /**
     * 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 通过名字我们就知道这个计算信号量,也就是控制获取资源的许可证。

    主要的方法:

    // 构造方法设置可用资源的数量,即许可证的数量
    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 用法:

    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();
                }
            }
        }
    }
    
  • 相关阅读:
    私有继承基类函数如何被访问
    Song Form
    转载:Fork函数详解
    转载:bss段不占据磁盘空间的理解
    转载:大内高手—全局内存
    转载:内联函数 —— C 中关键字 inline 用法解析
    安装ubuntu16.04全过程,脱坑,修复the system is running in low-graphics mode
    C语言运算符优先级( * 与 ++)
    movsb movsw movsd 指令
    Linux文件属性
  • 原文地址:https://www.cnblogs.com/wolf-bin/p/8576787.html
Copyright © 2011-2022 走看看