并发工具类应用

2019-06-04  本文已影响0人  sunpy

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 交易出去 斯蒂芬库里
上一篇 下一篇

猜你喜欢

热点阅读