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

  • 相关阅读:
    AGC 015 E
    CF 1041 F. Ray in the tube
    AGC 005 D
    CF 348 D. Turtles
    2069: [POI2004]ZAW
    AGC 007 D
    zhengruioi 470 区间
    2653: middle
    Django 源码安装及使用
    Django MTV模型思想
  • 原文地址:https://www.cnblogs.com/hetaoyuan/p/11317029.html
Copyright © 2011-2022 走看看