zoukankan      html  css  js  c++  java
  • CountDownLatch、CyclicBarrier、Samephore浅谈三大机制

    CountDownLatch、CyclieBarrier与SamePhore都可用来控制线程的执行,那么他们之间有什么区别呢

    CountDownLatch

    CountDowenlatch可以看成一个线程等待多个线程,当多个线程执行完毕后最后线程才会执行

    话不多说。直接上代码

    /**
     * 一个线程等待多个线程,当多个线程都执行后
     * 等待的线程才会执行
     * @author chen
     *
     */
    public class CountDownLatchT {
        
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(5);
            for(int i=0;i<5;i++) {
                new Thread(()->{
                    countDownLatch.countDown();
                    System.out.println(Thread.currentThread().getName());
                },"线程"+i).start();
            }
            
            countDownLatch.await();
            System.out.println("main");
        }
    }

    可以看到,刚开始给要等待的线程数设置个初始值,这里为5,意思是要等待5个线程,在线程里,要显式的时候countDownLatch的countDown方法表明

    当前线程已经到了,将要等待的线程数减1,然后继续执行自己的代码。要等待的那个线程这里是main线程要使用countDownLatch的await方法进行等待。

    当所有线程都到达后并且都执行countdown方法后等待线程才会被唤醒执行。所以这段代码的结果是前面的5个线程都执行完后主线程才会执行。

    CyclicBarrier

    如果说countdownlatch是执行减操作,每到一个线程就减1,直到减为0,被阻塞的线程才执行的话。那么CyclicBarrier就可以看作是加操作了。先上代码。

    /**
     *     所有线程通过cyclicBarrier的await方法阻塞,直到最后一个线程到达后
     *     才唤醒所有线程,这时这些线程才能继续往下执行
     * @author chen
     *
     */
    public class CyclicBarrierT {
        
        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
            
            for(int i=0; i<5;i++) {
                new Thread(()->{
                    System.out.println(Thread.currentThread().getName()+"start");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"end");
                },"线程"+i).start();
            }
        }
    }

    CyclicBarrier的工作原理是多个线程等一个线程,当一个线程到达的时候就使用await方法进入屏障,直到最后一个线程到达屏障的时候

    屏障才会解除,所有到屏障的线程才会被唤醒继续往下执行。

    SamePhore

    SamePhore是信号量的意思,它的使用场景是多个线程使用有限个资源的情况。可以类比停车位,当汽车数大于停车位的时候一次只能有若干

    辆汽车进去停车场,当汽车从停车场开出来的时候其他汽车才能进入停车场。

    上代码

    /**
     * Semaphore限定一次只能有几个线程执行
     * 线程进入前使用acquire获取执行权
     * 结束后使用release释放执行权
     * @author chen
     *
     */
    public class SemaPhoreT {
        
        public static void main(String[] args) {
            
            Semaphore semaphore = new Semaphore(2);
            
            for(int i=0;i<10;i++) {
                new Thread(()->{
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName()+"启动了");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        semaphore.release();
                    }
                },"线程"+i).start();
            }
            
        }
    }

    上面代码信号量定义为2,线程数为10,因此我们执行的时候可以看到每次只有2个线程在运行。

  • 相关阅读:
    收集一些dos网络配置命令,从新获取ip刷新dns
    多个线程访问共享对象和数据的方式
    Oracle rownum 分页, 排序
    ORACLE中用rownum分页并排序的SQL语句
    CentOS 6.5安装MongoDB 2.6(多yum数据源)
    【编程练习】收集的一些c++代码片,算法排序,读文件,写日志,快速求积分等等
    java枚举使用详解
    PHP+MySQL动态网站开发从入门到精通(视频教学版)
    Premiere Pro CS6标准教程
    黑客攻防:实战加密与解密
  • 原文地址:https://www.cnblogs.com/czsy/p/10929244.html
Copyright © 2011-2022 走看看