最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程之同步工具類Exchanger

 更新時間:2021年10月28日 10:38:45   作者:冬日毛毛雨  
這篇文章主要介紹了Java多線程之同步工具類Exchanger,Exchanger 是一個用于線程間協(xié)作的工具類,Exchanger用于進行線程間的數(shù)據(jù)交換,它提供一個同步點,在這個同步點,兩個線程可以交換彼此的數(shù)據(jù),下面來看看具體內(nèi)容吧

1 Exchanger 介紹

前面分別介紹了CyclicBarrierCountDownLatch、Semaphore,現(xiàn)在介紹并發(fā)工具類中的最后一個Exchange。
Exchanger 是一個用于線程間協(xié)作的工具類,Exchanger用于進行線程間的數(shù)據(jù)交換,它提供一個同步點,在這個同步點,兩個線程可以交換彼此的數(shù)據(jù)。這兩個線程通過exchange 方法交換數(shù)據(jù),如果第一個線程先執(zhí)行exchange 方法,它會一直等待第二個線程也執(zhí)行exchange 方法,當(dāng)兩個線程都到達同步點時,這兩個線程就可以交換數(shù)據(jù)。

A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches with a partner thread, and receives its partner's object on return. An Exchanger may be viewed as a bidirectional form of a SynchronousQueue. Exchangers may be useful in applications such as genetic algorithms and pipeline designs.

在以上的描述中,有幾個要點:

  • 此類提供對外的操作是同步的;
  • 用于成對出現(xiàn)的線程之間交換數(shù)據(jù);
  • 可以視作雙向的同步隊列;
  • 可應(yīng)用于基因算法、流水線設(shè)計等場景。
  • 接著看api文檔,這個類提供對外的接口非常簡潔,一個無參構(gòu)造函數(shù),兩個重載的范型exchange方法:
public V exchange(V x) throws InterruptedException
public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

2 Exchanger 實例

public class ExchangerTest {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        final Exchanger exchanger = new Exchanger();
        executor.execute(new Runnable() {
            String data = "data1";

            @Override
            public void run() {
                doExchangeWork(data, exchanger);
            }
        });

        executor.execute(new Runnable() {
            String data = "data2";

            @Override
            public void run() {
                doExchangeWork(data, exchanger);
            }
        });
        executor.shutdown();
    }

    private static void doExchangeWork(String data, Exchanger exchanger) {
        try {
            System.out.println(Thread.currentThread().getName() + "正在把數(shù)據(jù) " + data + " 交換出去");
            Thread.sleep((long) (Math.random() * 1000));

            String exchangeData = (String) exchanger.exchange(data);
            System.out.println(Thread.currentThread().getName() + "交換得到數(shù)據(jù)  " + exchangeData);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

pool-1-thread-1正在把數(shù)據(jù) data1 交換出去
pool-1-thread-2正在把數(shù)據(jù) data2 交換出去
pool-1-thread-2交換得到數(shù)據(jù)  data1
pool-1-thread-1交換得到數(shù)據(jù)  data2

當(dāng)線程A調(diào)用Exchange對象的exchange()方法后,他會陷入阻塞狀態(tài),直到線程B也調(diào)用了exchange()方法,然后以線程安全的方式交換數(shù)據(jù),之后線程A和B繼續(xù)運行。

exchange等待超時

public class ExchangerTest {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        final Exchanger exchanger = new Exchanger();
        executor.execute(new Runnable() {
            String data = "data1";

            @Override
            public void run() {
                doExchangeWork(data, exchanger);
            }
        });

        executor.execute(new Runnable() {
            String data = "data2";

            @Override
            public void run() {
                try {
                    Thread.sleep((long) (3000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                doExchangeWork(data, exchanger);
            }
        });
        executor.shutdown();
    }

    private static void doExchangeWork(String data, Exchanger exchanger) {
        try {
            System.out.println(Thread.currentThread().getName() + "正在把數(shù)據(jù) " + data + " 交換出去");

            //遠小于3秒拋出異常
            String exchangeData = (String) exchanger.exchange(data,1, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName() + "交換得到數(shù)據(jù)  " + exchangeData);
        } catch ( TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

pool-1-thread-1正在把數(shù)據(jù) data1 交換出去
java.util.concurrent.TimeoutException
    at java.util.concurrent.Exchanger.exchange(Exchanger.java:626)
    at ExchangerTest.doExchangeWork(ExchangerTest.java:37)
    at ExchangerTest.access$000(ExchangerTest.java:3)
    at ExchangerTest$1.run(ExchangerTest.java:12)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
pool-1-thread-2正在把數(shù)據(jù) data2 交換出去
java.util.concurrent.TimeoutException
    at java.util.concurrent.Exchanger.exchange(Exchanger.java:626)
    at ExchangerTest.doExchangeWork(ExchangerTest.java:37)
    at ExchangerTest.access$000(ExchangerTest.java:3)
    at ExchangerTest$2.run(ExchangerTest.java:26)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

實戰(zhàn)場景:

設(shè)計一個定時任務(wù),每日凌晨執(zhí)行。在定時任務(wù)中啟動兩個線程,一個線程負責(zé)對業(yè)務(wù)明細表(xxx_info)進行查詢統(tǒng)計,把統(tǒng)計的結(jié)果放置在內(nèi)存緩沖區(qū),另一個線程負責(zé)讀取緩沖區(qū)中的統(tǒng)計結(jié)果并插入到業(yè)務(wù)統(tǒng)計表(xxx_statistics)中。
親,這樣的場景是不是聽起來很有感覺?沒錯!兩個線程在內(nèi)存中批量交換數(shù)據(jù),這個事情我們可以使用Exchanger去做!

3 實現(xiàn)原理

Exchanger(交換者)是一個用于線程間協(xié)作的工具類。Exchanger用于進行線程間的數(shù)據(jù)交換。它提供一個同步點,在這個同步點兩個線程可以交換彼此的數(shù)據(jù)。這兩個線程通過exchange方法交換數(shù)據(jù), 如果第一個線程先執(zhí)行exchange方法,它會一直等待第二個線程也執(zhí)行exchange,當(dāng)兩個線程都到達同步點時,這兩個線程就可以交換數(shù)據(jù),將本線程生產(chǎn)出來的數(shù)據(jù)傳遞給對方。因此使用Exchanger的重點是成對的線程使用exchange()方法,當(dāng)有一對線程達到了同步點,就會進行交換數(shù)據(jù)。因此該工具類的線程對象是成對的。
Exchanger類提供了兩個方法,String exchange(V x):用于交換,啟動交換并等待另一個線程調(diào)用exchange;String exchange(V x,long timeout,TimeUnit unit):用于交換,啟動交換并等待另一個線程調(diào)用exchange,并且設(shè)置最大等待時間,當(dāng)?shù)却龝r間超過timeout便停止等待。

到此這篇關(guān)于Java多線程之同步工具類Exchanger的文章就介紹到這了,更多相關(guān)Java多線程 Exchanger內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java JDK1.5、1.6、1.7新特性整理

    Java JDK1.5、1.6、1.7新特性整理

    這篇文章主要介紹了Java JDK1.5、1.6、1.7新特性整理,需要的朋友可以參考下
    2016-10-10
  • SpringMVC底層執(zhí)行流程及原理解析

    SpringMVC底層執(zhí)行流程及原理解析

    這篇文章主要介紹了SpringMVC底層執(zhí)行流程及原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • Spring Boot項目實戰(zhàn)之?dāng)r截器與過濾器

    Spring Boot項目實戰(zhàn)之?dāng)r截器與過濾器

    這篇文章主要介紹了Spring Boot項目實戰(zhàn)之?dāng)r截器與過濾器,文中給大家詳細介紹了springboot 攔截器和過濾器的基本概念,過濾器的配置,需要的朋友可以參考下
    2018-01-01
  • Java多線程環(huán)境下使用的集合類示例詳解

    Java多線程環(huán)境下使用的集合類示例詳解

    這篇文章主要給大家介紹了關(guān)于Java多線程環(huán)境下使用的集合類的相關(guān)資料,開發(fā)過程中經(jīng)常遇到這種需求,文中通過代碼示例和圖文介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • Spring Boot 端口被占用的解決方法

    Spring Boot 端口被占用的解決方法

    這篇文章主要介紹了解決 Spring Boot 端口被占用的方法詳解,通過本文的介紹,你學(xué)習(xí)了如何解決 Spring Boot 端口被占用的問題。你了解了檢查端口是否被占用、停止占用端口的進程、更改應(yīng)用程序的端口號以及檢查應(yīng)用程序間的端口沖突等方法,需要的朋友可以參考下
    2023-07-07
  • Java使用JDBC實現(xiàn)Oracle用戶認證的方法詳解

    Java使用JDBC實現(xiàn)Oracle用戶認證的方法詳解

    這篇文章主要介紹了Java使用JDBC實現(xiàn)Oracle用戶認證的方法,結(jié)合實例形式分析了java使用jdbc實現(xiàn)數(shù)據(jù)庫連接、建表、添加用戶、用戶認證等操作流程與相關(guān)注意事項,需要的朋友可以參考下
    2017-08-08
  • SSM 實現(xiàn)登錄驗證碼功能(附源碼)

    SSM 實現(xiàn)登錄驗證碼功能(附源碼)

    這篇文章主要介紹了SSM 實現(xiàn)登錄驗證碼功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-12-12
  • ThreadLocal內(nèi)存泄漏常見要點解析

    ThreadLocal內(nèi)存泄漏常見要點解析

    這篇文章主要介紹了ThreadLocal內(nèi)存泄漏常見要點,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • Java四種常用線程池的詳細介紹

    Java四種常用線程池的詳細介紹

    今天小編就為大家分享一篇關(guān)于Java四種常用線程池的詳細介紹,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java實現(xiàn)冒泡排序算法及對其的簡單優(yōu)化示例

    Java實現(xiàn)冒泡排序算法及對其的簡單優(yōu)化示例

    這篇文章主要介紹了Java實現(xiàn)冒泡排序算法及對其的簡單優(yōu)化示例,冒泡排序的最差時間復(fù)雜度為O(n^2),最優(yōu)時間復(fù)雜度為O(n),存在優(yōu)化的余地,需要的朋友可以參考下
    2016-05-05

最新評論

霍林郭勒市| 晋城| 和静县| 永丰县| 西青区| 刚察县| 通州市| 中宁县| 平凉市| 阿克苏市| 深泽县| 梅州市| 凤冈县| 胶南市| 横山县| 辽阳县| 古丈县| 台北县| 正蓝旗| 临朐县| 阜宁县| 广东省| 富平县| 扶余县| 德昌县| 磐石市| 九江县| 湟源县| 军事| 莒南县| 吉木乃县| 那曲县| 乐昌市| 墨竹工卡县| 鄯善县| 巨鹿县| 额尔古纳市| 岳阳市| 色达县| 将乐县| 沿河|