(十二)java多線程之Exchanger

本人郵箱: <kco1989@qq.com>
歡迎轉載,轉載請註明網址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經所有託管github有須要的同窗自行下載java

引言

今天咱們講最後一個同步工具類Exchanger,這個比較簡單,就是讓兩個線程交換數據.git

理論

Exchanger只有兩個方法而已,並且兩個仍是同樣的,只是參數不通而已github

  • exchange(V x) 跟另一個線程交換數據x,若是另一個線程的數據準備好,那麼當前線程會馬上返回,並得到另一個線程的數據;不然當前線程會進入等待狀態微信

  • V exchange(V x, long timeout, TimeUnit unit): 跟exchange,若是會有一個指定的超時時間,若是在等待時間超時了,並且尚未收到對方的數據的話,則會拋出TimeoutException異常dom

例子 有耐心的山治和路飛

看過海賊王的人都知道山治和路飛,山治是一個廚師,手藝那是槓槓的.路飛則是一個大胃王,超能吃.如今編寫一個程序,讓山治不斷給路飛作食物,而路飛不斷吃,吃完以後要對山治說感謝.ok,開始編碼ide

  • 先編寫一個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<String> exchanger;
    Random random = new Random();
    public ShanZhiRunnable(Exchanger<String> 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();
            }
        }

    }
}
  • 而後編寫路飛吃飯的類 LuFeiRunnablethis

public class LuFeiRunnable implements Runnable{
    Exchanger<String> exchanger;
    Random random = new Random();
    public LuFeiRunnable(Exchanger<String> 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<String> exchanger = new Exchanger<>();
        new Thread(new LuFeiRunnable(exchanger)).start();
        new Thread(new ShanZhiRunnable(exchanger)).start();
    }
}

運行結果以下,並截取部分輸出

==>山治開始作 一品鮑魚
==>山治把 一品鮑魚 給作好了,給路飛送過去
==>山治收到路飛的評語:開吃啦...
==>山治開始作 芝麻肉絲
--->路飛拿到山治作的菜: 一品鮑魚
==>山治把 芝麻肉絲 給作好了,給路飛送過去
--->路飛吃完一品鮑魚
--->路飛拿到山治作的菜: 芝麻肉絲
==>山治收到路飛的評語:一品鮑魚太好吃!太感謝山治了...
==>山治開始作 雞蛋炒西紅柿
--->路飛吃完芝麻肉絲
==>山治把 雞蛋炒西紅柿 給作好了,給路飛送過去
==>山治收到路飛的評語:芝麻肉絲太好吃!太感謝山治了...
--->路飛拿到山治作的菜: 雞蛋炒西紅柿
==>山治開始作 油豆腐鑲肉
==>山治把 油豆腐鑲肉 給作好了,給路飛送過去
--->路飛吃完雞蛋炒西紅柿
--->路飛拿到山治作的菜: 油豆腐鑲肉
==>山治收到路飛的評語:雞蛋炒西紅柿太好吃!太感謝山治了...
==>山治開始作 梅菜蒸魚尾
==>山治把 梅菜蒸魚尾 給作好了,給路飛送過去
--->路飛吃完油豆腐鑲肉
==>山治收到路飛的評語:油豆腐鑲肉太好吃!太感謝山治了...
==>山治開始作 炸子雞
--->路飛拿到山治作的菜: 梅菜蒸魚尾
==>山治把 炸子雞 給作好了,給路飛送過去
--->路飛吃完梅菜蒸魚尾
--->路飛拿到山治作的菜: 炸子雞
==>山治收到路飛的評語:梅菜蒸魚尾太好吃!太感謝山治了...
==>山治開始作 翠竹粉蒸魚
==>山治把 翠竹粉蒸魚 給作好了,給路飛送過去
--->路飛吃完炸子雞
--->路飛拿到山治作的菜: 翠竹粉蒸魚
==>山治收到路飛的評語:炸子雞太好吃!太感謝山治了...
==>山治開始作 風情羊柳
==>山治把 風情羊柳 給作好了,給路飛送過去

例子2 沒耐心的山治和路飛

如今假設他們倆都沒有耐心,不想一直等一下

  • LuFeiRunnable修改成:

public class LuFeiRunnable implements Runnable{
    Exchanger<String> exchanger;
    Random random = new Random();
    public LuFeiRunnable(Exchanger<String> 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<String> exchanger;
    Random random = new Random();
    public ShanZhiRunnable(Exchanger<String> 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應該沒有什麼難度.好的,這篇就到這裏.

打賞

若是以爲個人文章寫的還過得去的話,有錢就捧個錢場,沒錢給我捧我的場(幫我點贊或推薦一下)
微信打賞
支付寶打賞

相關文章
相關標籤/搜索