美文网首页
并发工具类应用

并发工具类应用

作者: sunpy | 来源:发表于2019-06-04 22:46 被阅读0次

1. CountDownLatch应用

场景

日常操作:老爸出去买菜,老妈去逛街买衣服,然后两人集合一起打车回家。

实现

public class ConcurrentTest {

    private static final CountDownLatch cdl = new CountDownLatch(2);
    
    public static void main(String[] args) {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 
                2, 
                10, 
                TimeUnit.SECONDS, 
                new ArrayBlockingQueue<Runnable>(10));
        
        tpe.allowCoreThreadTimeOut(true);
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                    System.out.println("老爸买菜");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    cdl.countDown();
                }
            }
        });
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                    System.out.println("老妈逛街买衣服");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    cdl.countDown();
                }
            }
        });
        
        try {
            cdl.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("一起坐车回家");
    }
}

总结:
CountDownLatch的特点等待前n个线程执行完之后再执行。但是缺点就是一次性的,不可以重置。


2. CyclicBarrier应用

场景

日常操作:老爸陪老妈逛街一起出门打车,老爸在家先收拾家务,老妈化妆,然后一起打车出门。

实现

public class CyclicBarrierTest {

    private static final CyclicBarrier cb = new CyclicBarrier(2, new Runnable() {
        
        @Override
        public void run() {
            System.out.println("一起打车出门");
        }
    });
    
    public static void main(String[] args) {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 
                2, 
                20, 
                TimeUnit.SECONDS, 
                new ArrayBlockingQueue<Runnable>(10));
        tpe.allowCoreThreadTimeOut(true);
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    System.out.println("老爸收拾家务");
                    cb.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                } 
            }
        });
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    System.out.println("老妈化妆");
                    cb.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                } 
            }
        });
    }
}

结果:

老爸收拾家务
老妈化妆
一起打车出门

总结:
多个线程到达指定的屏障点,才可以执行。最后一个线程到达屏障后,最后执行的线程在构造器传入。还可以通过reset方法还可以重置屏障为初始化状态。


3. Semaphore应用

场景

桥只能允许两个人,多一个人上桥就会落水,所以只能保证桥上的人流量为2人。

实现

public class SemaphoreTest {

    private static final Semaphore semaphore = new Semaphore(2);
    
    public static void main(String[] args) {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 
                2, 
                20, 
                TimeUnit.SECONDS, 
                new ArrayBlockingQueue<Runnable>(10));
        
        tpe.allowCoreThreadTimeOut(true);
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " 上桥");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " 上桥");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + " 下桥");
                    
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " 上桥");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

结果:

pool-1-thread-1 上桥
pool-1-thread-2 上桥
pool-1-thread-1 下桥
pool-1-thread-1 上桥

4. Exchanger应用

场景

两支球队,相互交易球员,一个交易出勒布朗詹姆斯,一个交易出斯蒂芬库里。

实现

public class ExchangerTest {

    private static final Exchanger<String> exchanger = new Exchanger<String>();
    
    public static void main(String[] args) {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 
                2, 
                15, 
                TimeUnit.SECONDS, 
                new ArrayBlockingQueue<Runnable>(10));
        tpe.allowCoreThreadTimeOut(true);
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    String outputStr = " 勒布朗詹姆斯";
                    String inputStr = exchanger.exchange(outputStr);
                    System.out.println(Thread.currentThread().getName() + " 交易进来" + inputStr);
                    System.out.println(Thread.currentThread().getName() + " 交易出去" + outputStr);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        tpe.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    String outputStr = " 斯蒂芬库里";
                    String inputStr = exchanger.exchange(outputStr);
                    System.out.println(Thread.currentThread().getName() + " 交易进来" + inputStr);
                    System.out.println(Thread.currentThread().getName() + " 交易出去" + outputStr);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

结果:

pool-1-thread-1 交易进来 斯蒂芬库里
pool-1-thread-2 交易进来 勒布朗詹姆斯
pool-1-thread-1 交易出去 勒布朗詹姆斯
pool-1-thread-2 交易出去 斯蒂芬库里

相关文章

  • 并发工具类应用

    1. CountDownLatch应用 场景 日常操作:老爸出去买菜,老妈去逛街买衣服,然后两人集合一起打车回家。...

  • Java并发编程之工具类

    一、并发工具类 JDK1.5 引入常用并发工具类:CountDownLatch/Semaphore/CyclicB...

  • 高并发(9)- 线程并发工具类-CyclicBarrier

    @[TOC](高并发(9)- 线程并发工具类-CyclicBarrier) 前言 上篇文章讲解了线程的并发工具类之...

  • 高并发(10)- 线程并发工具类-Semaphore

    @[TOC](高并发(10)- 线程并发工具类-Semaphore) 前言 上篇文章讲解了线程的并发工具类之Cyc...

  • Java 并发包提供了哪些并发工具类

    Java 并发包提供了哪些并发工具类 Java 基础并发工具类 提供了比 synchronized更加高级的各种同...

  • Java并发编程-3

    目录(1)并发工具类(2)原子自增类(3)线程池 一:并发工具类 CountDownLatch:允许一个或多个线程...

  • 并发工具类 Semaphore

    上篇介绍了内部使用AQS的并发工具类CountDownLatch,接下来我要介绍的并发工具类Semaphore内部...

  • 并发工具类

    ------本文主要记录CountDownLatch,CyclicBarries、Semaphore工具提供的并发...

  • 并发工具类

    CountDownLatch 简介 CountDownLatch 允许一个或多个线程等待其他线程完成操作。 使用场...

  • 并发工具类

    1.CountDownLatch await(),进入等待的状态countDown(),计数器减一应用场景:启动三...

网友评论

      本文标题:并发工具类应用

      本文链接:https://www.haomeiwen.com/subject/kdddxctx.html