zoukankan      html  css  js  c++  java
  • juc包下四大并发工具

    juc.CountDownLatch 闭锁

    一个线程在等待一组线程后再恢复执行

    await()等待其他线程执行完毕

    被等待线程执行完毕后计数器-1

    如何知道其他线程执行完了?

    计数器,若一组线程为,CountDown为5,减到0代表等待线程被全部执行完毕

    一次性工具:当Countdown的值减到0的时候再也无法恢复

    juc内部的代码都是lock体系来实现的

    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    
    // 运动员线程
    class CDLTask implements Runnable {
        private CountDownLatch countDownLatch;
    
        public CDLTask(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始跑步");
            try {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(Thread.currentThread().getName()+"到达终点");
                countDownLatch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    public class CountDownLatchDemo {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(4);
            CDLTask cdlTask = new CDLTask(countDownLatch);
            System.out.println("比赛开始...");
            new Thread(cdlTask,"运动员A").start();
            new Thread(cdlTask,"运动员B").start();
            new Thread(cdlTask,"运动员C").start();
            new Thread(cdlTask,"运动员D").start();
            // 等待所有线程都到达终点后再输出此语句
            countDownLatch.await();
            System.out.println("比赛结束...");
        }
    }


    juc.CyclicBarrier  循环栅栏

    一组线程同时到达临界点后再恢复执行(先到达临界点的线程会阻塞,直到所有线程都到达临界点)

    public CyclicBarrier(int parties, Runnable barrierAction)

    当多个线程同时到达临界点时,

    随机挑选一个线程执行barrierAction后再同时恢复执行

    计数器的值可以恢复

    await

    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.TimeUnit;
    
    class CBTask implements Runnable {
        private CyclicBarrier cyclicBarrier;
    
        public CBTask(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+
                    "正在写入数据...");
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+
                        "写入数据完毕,等待其他线程写入完毕...");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("所有线程均已写入完毕,继续恢复执行...");
        }
    }
    class CyclicBarrierDemo {
        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(4
                    ,() -> {
                System.out.println("当前线程为:"+Thread.currentThread().getName());
            });
            CBTask cbTask = new CBTask(cyclicBarrier);
            for (int i = 0; i < 4; i++) {
                new Thread(cbTask,"写线程"+(i+1)).start();
            }
        }
    }


    juc.Exchanger 线程交换器

    用于两个线程直线的数据交换,当Exchanger只有一个线程时,该线程会阻塞直到有别的线程
    调用exchange进入缓冲区,当前线程与新线程交换数据后同时恢复执行。
    import java.util.concurrent.Exchanger;
    import java.util.concurrent.TimeUnit;
    
    
    class ExchangerDemo {
        public static void main(String[] args) {
            Exchanger<String> exchanger = new Exchanger<>();
            Thread girlThread = new Thread(() -> {
                try {
                    String girl = exchanger.exchange("我喜欢你.....");
                    System.out.println("女生说:"+girl);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            girlThread.start();
            Thread boyThread = new Thread(() -> {
                System.out.println("女神缓缓步入眼帘...");
                try {
                    TimeUnit.SECONDS.sleep(1);
                    String boy = exchanger.exchange("我喜欢你!");
                    System.out.println("男生说:"+boy);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            boyThread.start();
        }
    }
    
    


    juc.Semaphore 信号量

    acquire() : 尝试占用一个信号量,失败的线程会阻塞直到有新的信号量

    release() : 释放一个信号量

    acquire(int n) : 尝试占用n个信号量,失败的线程会阻塞直到有新的信号量

    release(int n) : 释放n个信号量
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.TimeUnit;
    
    
    class SemaphoreTask implements Runnable {
        private Semaphore semaphore;
    
        public SemaphoreTask(Semaphore semaphore) {
            this.semaphore = semaphore;
        }
    
        @Override
        public void run() {
            try {
                semaphore.acquire(2);
                System.out.println(Thread.currentThread()
                        .getName()+"占用2台设备生产");
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread()
                        .getName()+"生产完毕,释放设备");
                semaphore.release(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    class SemaphoreDemo {
        public static void main(String[] args) {
            Semaphore semaphore = new Semaphore(5);
            SemaphoreTask task = new SemaphoreTask(semaphore);
            for (int i = 0; i < 8; i++) {
                new Thread(task,"工人"+(i+1)).start();
            }
        }
    }

     这里有一篇比较好的博客关于cyclicbarrier和countdownlatch的区别:

    https://blog.csdn.net/liangyihuai/article/details/83106584

  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/hetaoyuan/p/11317029.html
Copyright © 2011-2022 走看看