zoukankan      html  css  js  c++  java
  • java基础----CountDownLatch、CyclicBarrier

      CountDownLatch是juc包里面的一个计数器,用户可以为他设置一个初始值,并调用他的await()方法使当前线程转变为阻塞状态,直到CountDownLatch计数完毕。

      Enum是java中的枚举,当程序运行过程中需要根据一定的对应关系去获取一些数据的时候,通过数据库去拿这些数据是非常消耗性能的,因为中间有创建和销毁数据库连接的消耗,因此,可以用枚举来实现这些功能。

      下面通过一个例子来理解这两个东西

    import java.util.Random;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    public class CountDownLatchDemo {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(6);
            Random rd = new Random();
    
            System.out.println(Thread.currentThread().getName() + "线程开始");
            for(int i = 0; i < 6; i++)
            {
                new Thread(()->{
                    try {
                        System.out.println(Thread.currentThread().getName() + "线程开始");
                        TimeUnit.SECONDS.sleep(rd.nextInt(5));
                        System.out.println(Thread.currentThread().getName() + "线程结束");
                        countDownLatch.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                },ThreadEnum.getThreadNameByKey(i).getRetMessage()).start();
            }
    
            countDownLatch.await();
            System.out.println(Thread.currentThread().getName() + "线程结束");
        }
    }

      在上述代码中,我们希望main线程在所有子线程都结束后才结束,因此在main线程中加入了countDownLatch.awati()方法,而每个子线程结束的时候,都会让countDownLatch -  1。值得一提的是,在获取线程名的时候,代码里面使用了枚举的方式去获取,ThreadEnum.getThreadNameByKey(i).getRetMessage()。枚举具体的代码如下:

    import jdk.nashorn.internal.objects.annotations.Getter;
    
    public enum ThreadEnum {
        ONE(0,"a"),
        TWO(1,"b"),
        THREE(2,"c"),
        FOUR(3,"d"),
        FIVE(4,"e"),
        SIX(5,"f");
    
        private Integer retCode;
        private String retMessage;
    
        public Integer getRetCode() {
            return retCode;
        }
    
        public void setRetCode(Integer retCode) {
            this.retCode = retCode;
        }
    
        public String getRetMessage() {
            return retMessage;
        }
    
        public void setRetMessage(String retMessage) {
            this.retMessage = retMessage;
        }
    
        ThreadEnum(Integer retCode, String retMessage)
        {
            this.retCode = retCode;
            this.retMessage = retMessage;
        }
    
        public static ThreadEnum getThreadNameByKey(int index)
        {
            ThreadEnum[] myArray = ThreadEnum.values();
            for(ThreadEnum element : myArray) {
                if(index == element.getRetCode())
                {
                    return element;
                }
            }
            return null;
        }
    }

      

      CyclicBarrier与CountDownLatch不同,如果说CountDownLatch相当于在做一个减法操作的话,那么CyclicBarrier就是在做一个加法操作,CyclicBarrier中会设置一个parties和一个runnabled,parties代表着需要多少个线程进来之后,才会执行runnabled里面的逻辑。而每个线程调用CyclicBarrier中的await方法后,就会进入到CyclicBarrier的计数当中,并切换到阻塞状态,直到指定数量的线程都进来CyclicBarrier后,屏障解除,各线程继续执行,同时运行CyclicBarrier中runnabled中的逻辑。

      如下列代码

    import java.util.Random;
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.TimeUnit;
    
    public class CydicBarrierDemo {
        public static void main(String[] args) {
            Random rd = new Random();
            CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
                System.out.println("终极任务开始");
            });
    
            for(int i = 0; i < 7; i ++)
            {
                new Thread(()->{
                    try {
                        System.out.println(Thread.currentThread().getName() + "	线程启动了");
                        TimeUnit.SECONDS.sleep(rd.nextInt(5));
                        System.out.println(Thread.currentThread().getName() + "	线程变为阻塞状态了");
                        cyclicBarrier.await();
                        System.out.println(Thread.currentThread().getName() + "	线程重新运行了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                },"t"+i).start();
            }
        }
    }

        

  • 相关阅读:
    easyui的datagrid分页写法小结
    @ResponseBody
    JSONObject.parseObject(jsonStr);和JSONObject.fromObject(jsonStr);
    测试cnblogs的代码折叠展开功能和zoom.js实现图片放大缩小冲突的问题
    使用git将项目上传到github(最简单方法)
    @Transactional注解事务不回滚不起作用无效
    SpringBoot开发项目,引入JPA找不到findOne方法
    mysql8.0 Authentication plugin 'caching_sha2_password' cannot be loaded
    Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释
    java 获取计算机名称, ip, mac地址
  • 原文地址:https://www.cnblogs.com/QicongLiang/p/13652055.html
Copyright © 2011-2022 走看看