资讯专栏INFORMATION COLUMN

(十二)java多线程之Exchanger

Flands / 3368人阅读

摘要:本人邮箱欢迎转载转载请注明网址代码已经全部托管有需要的同学自行下载引言今天我们讲最后一个同步工具类这个比较简单就是让两个线程交换数据理论只有两个方法而已而且两个还是一样的只是参数不通而已跟另外一个线程交换数据如果另外一个线程的数据准备好那么

本人邮箱:
欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代码已经全部托管github有需要的同学自行下载

引言

今天我们讲最后一个同步工具类Exchanger,这个比较简单,就是让两个线程交换数据.

理论

Exchanger只有两个方法而已,而且两个还是一样的,只是参数不通而已

exchange(V x) 跟另外一个线程交换数据x,如果另外一个线程的数据准备好,那么当前线程会立刻返回,并获得另外一个线程的数据;否则当前线程会进入等待状态

V exchange(V x, long timeout, TimeUnit unit): 跟exchange,如果会有一个指定的超时时间,如果在等待时间超时了,而且还没有收到对方的数据的话,则会抛出TimeoutException异常

例子 有耐心的山治和路飞

看过海贼王的人都知道山治和路飞,山治是一个厨师,手艺那是杠杠的.路飞则是一个大胃王,超能吃.现在编写一个程序,让山治不断给路飞做食物,而路飞不断吃,吃完之后要对山治说感谢.ok,开始编码

先编写一个Food食物类,这个比较简单,就是定义一些食物

public class Food {
    public final static String[] food = {
            "打边炉","奶味芦笋汤","糟片鸭","烤花揽桂鱼","苦中作乐","七星丸","鸭黄豆腐","贝丝扒菜胆","脆炒南瓜丝","龙凤双腿",
            //省略部分代码....
    };

    private static Random random = new Random();
    public static String getRandomFood(){
        return food[random.nextInt(food.length)];
    }
}

之后编写山治做菜的类 ShanZhiRunnable

public class ShanZhiRunnable implements Runnable{
    Exchanger exchanger;
    Random random = new Random();
    public ShanZhiRunnable(Exchanger exchanger) {
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        while (true){
            try {
                String food = Food.getRandomFood();
                System.out.println("==>山治开始做 " + food);
                Thread.sleep(random.nextInt(500));
                System.out.println("==>山治把 " + food + " 给做好了,给路飞送过去");
                String exchange = exchanger.exchange(food);
                System.out.println("==>山治收到路飞的评语:" + exchange);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

然后编写路飞吃饭的类 LuFeiRunnable

public class LuFeiRunnable implements Runnable{
    Exchanger exchanger;
    Random random = new Random();
    public LuFeiRunnable(Exchanger exchanger) {
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        String temp = "开吃啦...";
        while (true){
            try {
                String food = exchanger.exchange(temp);
                System.out.println("--->路飞拿到山治做的菜: " + food);
                Thread.sleep(random.nextInt(500));
                System.out.println("--->路飞吃完" + food);
                temp = food + "太好吃!太感谢山治了...";
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

最后编写测试类 TestMain

public class TestMain {
    public static void main(String[] args) {
        Exchanger exchanger = new Exchanger<>();
        new Thread(new LuFeiRunnable(exchanger)).start();
        new Thread(new ShanZhiRunnable(exchanger)).start();
    }
}

运行结果如下,并截取部分输出

==>山治开始做 一品鲍鱼
==>山治把 一品鲍鱼 给做好了,给路飞送过去
==>山治收到路飞的评语:开吃啦...
==>山治开始做 芝麻肉丝
--->路飞拿到山治做的菜: 一品鲍鱼
==>山治把 芝麻肉丝 给做好了,给路飞送过去
--->路飞吃完一品鲍鱼
--->路飞拿到山治做的菜: 芝麻肉丝
==>山治收到路飞的评语:一品鲍鱼太好吃!太感谢山治了...
==>山治开始做 鸡蛋炒西红柿
--->路飞吃完芝麻肉丝
==>山治把 鸡蛋炒西红柿 给做好了,给路飞送过去
==>山治收到路飞的评语:芝麻肉丝太好吃!太感谢山治了...
--->路飞拿到山治做的菜: 鸡蛋炒西红柿
==>山治开始做 油豆腐镶肉
==>山治把 油豆腐镶肉 给做好了,给路飞送过去
--->路飞吃完鸡蛋炒西红柿
--->路飞拿到山治做的菜: 油豆腐镶肉
==>山治收到路飞的评语:鸡蛋炒西红柿太好吃!太感谢山治了...
==>山治开始做 梅菜蒸鱼尾
==>山治把 梅菜蒸鱼尾 给做好了,给路飞送过去
--->路飞吃完油豆腐镶肉
==>山治收到路飞的评语:油豆腐镶肉太好吃!太感谢山治了...
==>山治开始做 炸子鸡
--->路飞拿到山治做的菜: 梅菜蒸鱼尾
==>山治把 炸子鸡 给做好了,给路飞送过去
--->路飞吃完梅菜蒸鱼尾
--->路飞拿到山治做的菜: 炸子鸡
==>山治收到路飞的评语:梅菜蒸鱼尾太好吃!太感谢山治了...
==>山治开始做 翠竹粉蒸鱼
==>山治把 翠竹粉蒸鱼 给做好了,给路飞送过去
--->路飞吃完炸子鸡
--->路飞拿到山治做的菜: 翠竹粉蒸鱼
==>山治收到路飞的评语:炸子鸡太好吃!太感谢山治了...
==>山治开始做 风情羊柳
==>山治把 风情羊柳 给做好了,给路飞送过去
例子2 没耐心的山治和路飞

现在假设他们俩都没有耐心,不想一直等一下

LuFeiRunnable修改为:

public class LuFeiRunnable implements Runnable{
    Exchanger exchanger;
    Random random = new Random();
    public LuFeiRunnable(Exchanger exchanger) {
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        String temp = "开吃啦...";
        while (true){
            try {
                String food = exchanger.exchange(temp, 300, TimeUnit.MILLISECONDS);
                System.out.println("--->路飞吃完" + food);
                temp = food + "太好吃!太感谢山治了...";
                Thread.sleep(random.nextInt(500));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                System.out.println("--->路飞等的不耐烦了,不想等......开始喝起 东北风" );
            }
        }
    }
}

ShanZhiRunnable修改为

public class ShanZhiRunnable implements Runnable{
    Exchanger exchanger;
    Random random = new Random();
    public ShanZhiRunnable(Exchanger exchanger) {
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        while (true){
            String food = Food.getRandomFood();
            try {
                System.out.println("==>山治开始做 " + food);
                Thread.sleep(random.nextInt(500));
                System.out.println("==>山治把 " + food + " 给做好了,给路飞送过去");
                String exchange = exchanger.exchange(food, 300, TimeUnit.MILLISECONDS);
                System.out.println("==>山治收到路飞的评语:" + exchange);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                System.out.println("==>山治等的不耐烦了,不想等......,把 " + food + " 其他船员吃了");
            }
        }

    }
}

运行一下程序:

==>山治开始做 辣子肉丁
--->路飞等的不耐烦了,不想等......开始喝起 东北风
==>山治把 辣子肉丁 给做好了,给路飞送过去
==>山治收到路飞的评语:开吃啦...
==>山治开始做 砂锅三味
--->路飞吃完辣子肉丁
==>山治把 砂锅三味 给做好了,给路飞送过去
==>山治收到路飞的评语:辣子肉丁太好吃!太感谢山治了...
--->路飞吃完砂锅三味
==>山治开始做 甜椒肉丝
==>山治把 甜椒肉丝 给做好了,给路飞送过去
--->路飞吃完甜椒肉丝
==>山治收到路飞的评语:砂锅三味太好吃!太感谢山治了...
==>山治开始做 一品鲍鱼
==>山治把 一品鲍鱼 给做好了,给路飞送过去
==>山治等的不耐烦了,不想等......,把 一品鲍鱼 其他船员吃了
==>山治开始做 香酥凤腿
--->路飞等的不耐烦了,不想等......开始喝起 东北风
==>山治把 香酥凤腿 给做好了,给路飞送过去
==>山治收到路飞的评语:甜椒肉丝太好吃!太感谢山治了...
--->路飞吃完香酥凤腿
==>山治开始做 雪花片汤
==>山治把 雪花片汤 给做好了,给路飞送过去
--->路飞吃完雪花片汤
==>山治收到路飞的评语:香酥凤腿太好吃!太感谢山治了...
==>山治开始做 凤尾金鱼
==>山治把 凤尾金鱼 给做好了,给路飞送过去
==>山治收到路飞的评语:雪花片汤太好吃!太感谢山治了...
--->路飞吃完凤尾金鱼
==>山治开始做 三菇浸鱼云
--->路飞等的不耐烦了,不想等......开始喝起 东北风
==>山治把 三菇浸鱼云 给做好了,给路飞送过去
==>山治收到路飞的评语:凤尾金鱼太好吃!太感谢山治了...
--->路飞吃完三菇浸鱼云
==>山治开始做 辣子鸡丁
==>山治把 辣子鸡丁 给做好了,给路飞送过去
==>山治收到路飞的评语:三菇浸鱼云太好吃!太感谢山治了...
--->路飞吃完辣子鸡丁
==>山治开始做 梅干菜烧肉

通过以上两个例子,掌握Exchanger应该没有什么难度.好的,这篇就到这里.

打赏

如果觉得我的文章写的还过得去的话,有钱就捧个钱场,没钱给我捧个人场(帮我点赞或推荐一下)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69925.html

相关文章

  • Java线程编程同步器

    摘要:倒计时锁,线程中调用使进程进入阻塞状态,当达成指定次数后通过继续执行每个线程中剩余的内容。实现分阶段的的功能测试代码拿客网站群三产创建于年月日。 同步器 为每种特定的同步问题提供了解决方案 Semaphore Semaphore【信号标;旗语】,通过计数器控制对共享资源的访问。 测试类: package concurrent; import concurrent.th...

    liangdas 评论0 收藏0
  • (十五)java线程并发集合ArrayBlockingQueue

    摘要:本人邮箱欢迎转载转载请注明网址代码已经全部托管有需要的同学自行下载引言做的同学们或多或少的接触过集合框架在集合框架中大多的集合类是线程不安全的比如我们常用的等等我们写一个例子看为什么说是不安全的例子证明是线程不安全的我们开启个线程每个线程向 本人邮箱: 欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kcogithub: https://github...

    stefan 评论0 收藏0
  • Java线程进阶(一)—— J.U.C并发包概述

    摘要:整个包,按照功能可以大致划分如下锁框架原子类框架同步器框架集合框架执行器框架本系列将按上述顺序分析,分析所基于的源码为。后,根据一系列常见的多线程设计模式,设计了并发包,其中包下提供了一系列基础的锁工具,用以对等进行补充增强。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首发于一世流云专栏:https...

    anonymoussf 评论0 收藏0
  • Java Exchanger交换线程

    摘要:使用一个交换两个线程的数据,交换期间该会被锁住,一般用于通信领域。当双方完成交换后,交换的就为的返回值。必须指定返回值的,否则该生产者生产的将不会与消费者的空进行交换。 Exchanger 使用一个pipeline交换两个线程的数据,交换期间该Slot会被锁住,一般用于通信领域。 该类提供两个方法 // k为交换对象 exchange(V k) //指定超时时间 e...

    刘德刚 评论0 收藏0
  • java并发编程学习Exchanger

    摘要:作用用来交换两个线程的数据。示例运行结果如下首先,会经过三秒后,才输出结果,说明两个线程没交换之前是阻塞的。 作用 用来交换两个线程的数据。 示例 public class ExchangerDemo { static Exchanger exchanger = new Exchanger(); static class Thread1 extends Thread ...

    lingdududu 评论0 收藏0

发表评论

0条评论

Flands

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<