zoukankan      html  css  js  c++  java
  • 并发工具类

    1.CountDownLatch:可以实现线程计数,阻塞后续线程
                    CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,

         此时就可以利用CountDownLatch来实现这种功能了。
                    countDown()实现计数器-1
                    await()等待拦截方法,等待计数器为0时再放行,否则则一直阻塞
                    getCount()获取当前计数器中计数数量
                    
                    案例:

                        /**
                         * 等待子线程全部执行完毕之后再执行主线程内容
                         * @param args
                         */
                        private static CountDownLatch countDownLatch=new CountDownLatch(2);
                        public static void main(String[] args) throws InterruptedException {
                            System.out.println("======主线程开始运行=====");
                            //第一个子线程
                            new Thread(()->{
                                System.out.println("子线程"+Thread.currentThread().getName()+"开始运行~");
                                //线程数量-1操作,通知该线程运行完毕
                                countDownLatch.countDown();
                            }).start();
    
                            //第二个子线程
                            new Thread(()->{
                                System.out.println("子线程"+Thread.currentThread().getName()+"开始运行~");
                                //线程数量-1操作,通知该线程运行完毕
                                countDownLatch.countDown();
                            }).start();
    
                            //等待,等待计数器中线程计数为0时才继续向下执行
                            countDownLatch.await();
                            System.out.println("子线程执行完毕,主线程继续执行");
    
    
    
                            //获取当前计数线程数量
                            /*while (true){
                                if(countDownLatch.getCount()==0){
                                    System.out.println("子线程执行完毕,主线程继续执行");
                                    break;
                                }
                            }*/
                        }
                    

                    
                    
                2.CyclicBarrier:类似于栅栏,进行拦截,等待所有线程都准备,然后统一放行,阻塞当前线程

                    //设置等待线程数量,当线程数量到达指定数量时,统一向下运行
                    private static CyclicBarrier cyclicBarrier=new CyclicBarrier(10);
                    public static void main(String[] args) {
                        //创建10个线程
                        for (int i = 1; i <=10 ; i++) {
                            new Thread(()->{
                                try {
                                    Thread.sleep(100);
                                    System.out.println(Thread.currentThread().getName()+"准备就绪");
                                    //等待
                                    cyclicBarrier.await();
                                } catch (InterruptedException | BrokenBarrierException e) {
                                    e.printStackTrace();
                                }
                                System.out.println(Thread.currentThread().getName()+"开始比赛~");
                            }).start();
                        }
                    }


                3.Semaphore:可以做资源控制,容器中有几个资源,那么线程执行时先申请资源,资源如果可用则继续执行,如果资源不可用则阻塞等待
                             当资源占用完毕之后将该资源释放,其他线程排队占用
                   

                        //最多允许三个线程同时执行    
            private static Semaphore semaphore=new Semaphore(3);
                        public static void main(String[] args) {
                            for (int i = 1; i <=5 ; i++) {
                                new Thread(()->{
                                    try {
                                        //申请资源,发生阻塞
                                        System.out.println(Thread.currentThread().getName()+"申请车位~");
                                        semaphore.acquire();
                                        System.out.println(Thread.currentThread().getName()+"可以停车了");
                                        //模拟上厕所时间
                                        Thread.sleep(1000);
                                        System.out.println(Thread.currentThread().getName()+"溜了溜了~");
                                        //释放资源
                                        semaphore.release();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }).start();
                            }
                        }


                    
                4.Exchanger:可以执行线程的资源交换,线程数量必须为偶数,因为是两两相互交换资源,如果不是偶数默认情况下导致阻塞,可以设置交换资源超时时间

        private static String str1="资源1";
        private static String str2="资源2";
        //构建资源交换对象
        private static Exchanger<String> stringExchanger=new Exchanger<>();
        public static void main(String[] args) {
            //第一个线程
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"初始占用资源:"+str1);
                //资源交换,将资源交给其他线程和获取到其他线程交换过来的资源
                try {
                    String newStr = stringExchanger.exchange(str1);
                    System.out.println(Thread.currentThread().getName()+"交换资源:"+newStr);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
    
            //第二个线程
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"初始占用资源:"+str2);
                //资源交换,将资源交给其他线程和获取到其他线程交换过来的资源
                try {
                    String newStr = stringExchanger.exchange(str2);
                    System.out.println(Thread.currentThread().getName()+"交换资源:"+newStr);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
    
            //第三个线程
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"初始占用资源:"+str2);
                //资源交换,将资源交给其他线程和获取到其他线程交换过来的资源
                try {
                    String newStr = stringExchanger.exchange(str2,1000, TimeUnit.MILLISECONDS);
                    System.out.println(Thread.currentThread().getName()+"交换资源:"+newStr);
                } catch (InterruptedException | TimeoutException e) {
                    e.printStackTrace();
                }
            }).start();
        }

  • 相关阅读:
    如何设置body高度为浏览器高度
    h5的video下载按钮如何隐藏
    微信小程序中的子父组件传值问题
    elementUI级联选择器2(选择及回显)编辑保存
    elementUI级联选择器(选择及回显)
    vue+elementUI 表格操作行的增删改查
    单独验证非form表单中的input(限制)
    JS中去除数组中的假值(0, 空,undefined, null, false)
    vue 组件之间的传值 (父子传值、兄弟传值)
    http协议的状态码
  • 原文地址:https://www.cnblogs.com/chx9832/p/12524379.html
Copyright © 2011-2022 走看看