并發(fā)工具類 Exchanger

簡(jiǎn)介

Exchanger(交換者),一個(gè)用于線程間協(xié)作的工具類。Exchanger用于線程間的數(shù)據(jù)交換,提供了一個(gè)同步點(diǎn),兩個(gè)線程可以在這個(gè)同步點(diǎn)交換彼此的數(shù)據(jù)。

構(gòu)造方法

Exchanger()

所有方法

exchange(V x)
等待另一個(gè)線程到達(dá)這個(gè)交換點(diǎn)(除非當(dāng)前線程interrupted),然后與另一線程交換數(shù)據(jù)對(duì)象。
exchange(V x, long timeout, TimeUnit unit)
等待另一個(gè)線程到達(dá)這個(gè)交換點(diǎn)(除非當(dāng)前線程interrupted或超過(guò)指定的等待時(shí)間),然后與另一線程交換數(shù)據(jù)對(duì)象。

簡(jiǎn)單示例

有個(gè)羊集,就是各家農(nóng)戶都拉著自家的羊來(lái)賣,或者來(lái)買幾只合適的羊。賣羊的和買羊的就可以看做是兩個(gè)線程,買羊的手里拿著錢,賣羊的手里牽著羊,這筆買賣交易成功后,買羊的手里就牽著羊,賣羊的手里就拿著錢了。

import java.util.concurrent.Exchanger;

/**
 * Created by bxw on 2017/12/3.
 */
public class SheepMarket {
    Exchanger<String> exchanger = new Exchanger<>();
    public static void main(String[] args) {
        SheepMarket sheepMarket = new SheepMarket();
        System.out.println("**************開(kāi)市了*************");
        SheepMarket.BuySheep buySheep = sheepMarket.new BuySheep();
        SheepMarket.SaleSheep saleSheep = sheepMarket.new SaleSheep();
        Thread thread1 = new Thread(buySheep);
        Thread thread2 = new Thread(saleSheep);
        thread1.start();
        thread2.start();
    }

    public  class BuySheep implements Runnable{
        String person = "買羊的說(shuō): ";
        String money = "我有1000塊錢";
        @Override
        public void run() {
            System.out.println(person + "我要買羊," + money);
            try {
                String sheep = exchanger.exchange(money);
                System.out.println(person + "羊買完了," + sheep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public class SaleSheep implements Runnable{
        String person = "賣羊的說(shuō): ";
        String sheep = "我手里牽著羊";
        @Override
        public void run() {
            System.out.println(person + "我要賣羊," + sheep);
            try {
                String money = exchanger.exchange(sheep);
                System.out.println(person + "羊賣完了," + money);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
image.png

上面的這個(gè)例子使用了exchange(V x)方法,下面再來(lái)看看exchange
(V x, long timeout, TimeUnit unit)這個(gè)方法,買羊的要買羊,賣羊的如果長(zhǎng)時(shí)間不理買羊的,買羊的就走了。
將BuySheep和SaleSheep稍作修改:

public class SheepMarket {
    Exchanger<String> exchanger = new Exchanger<>();
    public static void main(String[] args) {
        SheepMarket sheepMarket = new SheepMarket();
        System.out.println("**************開(kāi)市了*************");
        SheepMarket.BuySheep buySheep = sheepMarket.new BuySheep();
        SheepMarket.SaleSheep saleSheep = sheepMarket.new SaleSheep();
        Thread thread1 = new Thread(buySheep);
        Thread thread2 = new Thread(saleSheep);
        thread1.start();
        thread2.start();
    }

    public  class BuySheep implements Runnable{
        String person = "買羊的說(shuō): ";
        String money = "我有1000塊錢";
        @Override
        public void run() {
            System.out.println(person + "我要買羊," + money);
            try {
                String sheep = exchanger.exchange(money, 8000, TimeUnit.MILLISECONDS);
                System.out.println(person + "羊買完了," + sheep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
                System.err.println("麻蛋,不理我,老子還不買了");
            }
        }
    }

    public class SaleSheep implements Runnable{
        String person = "賣羊的說(shuō): ";
        String sheep = "我手里牽著羊";
        @Override
        public void run() {
            System.out.println(person + "我要賣羊," + sheep);
            try {
                Thread.sleep(9000);
                String money = exchanger.exchange(sheep);
                System.out.println(person + "羊賣完了," + money);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
image.png

把SaleSheep中Thread.sleep(9000)的睡眠時(shí)間縮短至8000以下依舊可以成功交換數(shù)據(jù)對(duì)象。

總結(jié)

如果兩個(gè)線程有一個(gè)沒(méi)有執(zhí)行exchange(V x)方法,就會(huì)一直等待,如果擔(dān)心有特殊情況發(fā)生,避免一直傻等,可以使用exchange(V x, long timeout, TimeUnit unit)。Exchanger還可用于校對(duì)工作,比如要對(duì)一批數(shù)據(jù)進(jìn)行錄入到excel,為了避免錯(cuò)誤,可有甲乙二人進(jìn)行錄入,然后由系統(tǒng)加載這兩個(gè)Excel,并比較是否錄入一致。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容