JUC学习之Exchanger

直接看代码吧

1package exchange; 2 3import java.util.concurrent.Exchanger; 4 5/** 6 * Exchanger让两个线程可以互换信息。 7 * 例子中服务生线程往空的杯子里倒水,顾客线程从装满水的杯子里喝水, 8 * 然后通过Exchanger双方互换杯子,服务生接着往空杯子里倒水,顾客接着喝水, 9 * 然后交换,如此周而复始。 10 */ 11public class ExchangerTest { 12 13    // 描述一个装水的杯子 14    public static class Cup{ 15        // 标识杯子是否有水 16        private boolean full = false; 17        public Cup(boolean full){ 18            this.full = full; 19        } 20        // 添水,假设需要5s 21        public void addWater(){ 22            if (!this.full){ 23                try { 24                    Thread.sleep(5000); 25                } catch (InterruptedException e) { 26                } 27                this.full = true; 28            } 29        } 30        // 喝水,假设需要10s 31        public void drinkWater(){ 32            if (this.full){ 33                try { 34                    Thread.sleep(10000); 35                } catch (InterruptedException e) { 36                } 37                this.full = false; 38            } 39        } 40    } 41     42    public static void testExchanger() { 43        //    初始化一个Exchanger,并规定可交换的信息类型是杯子 44        final Exchanger<Cup> exchanger = new Exchanger<Cup>(); 45        // 初始化一个空的杯子和装满水的杯子 46        final Cup initialEmptyCup = new Cup(false);  47        final Cup initialFullCup = new Cup(true); 48 49        //服务生线程 50        class Waiter implements Runnable { 51            public void run() { 52                Cup currentCup = initialEmptyCup; 53                try { 54                    int i=0; 55                    while (< 2){ 56                        System.out.println("服务生开始往杯子中添水:" 57                                + System.currentTimeMillis()); 58                        // 往空的杯子里加水 59                        currentCup.addWater(); 60                        System.out.println("服务生添水完毕:" 61                                + System.currentTimeMillis()); 62                        // 杯子满后和顾客的空杯子交换 63                        System.out.println("服务生等待与顾客交换杯子:" 64                                + System.currentTimeMillis()); 65                        currentCup = exchanger.exchange(currentCup); 66                        System.out.println("服务生与顾客交换杯子完毕:" 67                                + System.currentTimeMillis()); 68                        i++; 69                    } 70 71                } catch (InterruptedException ex) { 72                } 73            } 74        } 75 76        //顾客线程 77        class Customer implements Runnable { 78            public void run() { 79                Cup currentCup = initialFullCup; 80                try { 81                    int i=0; 82                    while (< 2){ 83                        System.out.println("顾客开始喝水:" 84                                + System.currentTimeMillis()); 85                        //把杯子里的水喝掉 86                        currentCup.drinkWater(); 87                        System.out.println("顾客喝水完毕:" 88                                + System.currentTimeMillis()); 89                        //将空杯子和服务生的满杯子交换 90                        System.out.println("顾客等待与服务生交换杯子:" 91                                + System.currentTimeMillis()); 92                        currentCup = exchanger.exchange(currentCup); 93                        System.out.println("顾客与服务生交换杯子完毕:" 94                                + System.currentTimeMillis()); 95                        i++; 96                    } 97                } catch (InterruptedException ex) { 98                } 99            } 100        } 101         102        new Thread(new Waiter()).start(); 103        new Thread(new Customer()).start(); 104    } 105     106    public static void main(String[] args) { 107        ExchangerTest.testExchanger(); 108    } 109}
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

遇见这么刁钻的面试题怎么办???Java怎么利用线程工厂监控线程池

@(https://shimo.im/docs/9GTP6XrJg9J88cJD/)明人不说暗话,直接开撸代码!!!ThreadFactory线程池中的线程从哪里来呢?就是ThreadFoctorycpublicinterfaceThreadFactoryThreadnewThread(Runnabler);Threadfactory里

4、jstack查看线程栈信息

1、介绍利用jps、top、jstack命令找到进程中耗时最大的线程,以及线程状态等等,同时最后还可以显示出死锁的线程查找:FoundoneJavaleveldeadlock即可1、jps获得进程号!(https://oscimg.oschina.net/oscnet/da00a309fa6

Android视频直播流(三) YUV 数据的存储,以及播放

上一章写了YUV数据的获取,这里写写怎么把YUV数据保存起来,以及播放吧。因为YUV数据,都是从camera的回调里拿到的,所以不可以对回调进行阻塞,所以最好的处理方式就是:定义一个队列,在camera的回调里只管往队列里塞数据,在外部,用一个线程,死循环,利用队列的特性:有

Java线程同步之一

一、线程同步线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序。同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务。每个服务员在同一时刻只能接待一个顾客的点餐,那么除了正在接待的顾客,其他人只能等待排队。当一个点餐服务完成之后,其他顾客就可以上去进行点餐。从这个例子中可以看到如下几个关注点:点餐服务

ThreadLocal 详解

概念ThreadLocal用于提供线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。也就是说ThreadLocal可以为每个线程创建一个【单独的变量副本】,相当于线程的privatestatic类型变量。使用示例publicclassThreadLocalTest{