日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SynchronousQueue详解

發布時間:2024/2/28 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SynchronousQueue详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • 舉例說明
  • 總結

SynchronousQueue詳解

簡介

SynchronousQueue是BlockingQueue的一種,所以SynchronousQueue是線程安全的。SynchronousQueue和其他的BlockingQueue不同的是SynchronousQueue的capacity是0。即SynchronousQueue不存儲任何元素。

也就是說SynchronousQueue的每一次insert操作,必須等待其他線性的remove操作。而每一個remove操作也必須等待其他線程的insert操作。

這種特性可以讓我們想起了Exchanger。和Exchanger不同的是,使用SynchronousQueue可以在兩個線程中傳遞同一個對象。一個線程放對象,另外一個線程取對象。

舉例說明

我們舉一個多線程中傳遞對象的例子。還是舉生產者消費者的例子,在生產者中我們創建一個對象,在消費者中我們取出這個對象。先看一下用CountDownLatch該怎么做:

@Testpublic void useCountdownLatch() throws InterruptedException {ExecutorService executor = Executors.newFixedThreadPool(2);AtomicReference<Object> atomicReference= new AtomicReference<>();CountDownLatch countDownLatch = new CountDownLatch(1);Runnable producer = () -> {Object object=new Object();atomicReference.set(object);log.info("produced {}",object);countDownLatch.countDown();};Runnable consumer = () -> {try {countDownLatch.await();Object object = atomicReference.get();log.info("consumed {}",object);} catch (InterruptedException ex) {log.error(ex.getMessage(),ex);}};executor.submit(producer);executor.submit(consumer);executor.awaitTermination(50000, TimeUnit.MILLISECONDS);executor.shutdown();}

上例中,我們使用AtomicReference來存儲要傳遞的對象,并且定義了一個型號量為1的CountDownLatch。

在producer中,我們存儲對象,并且countDown。

在consumer中,我們await,然后取出對象。

輸出結果:

[pool-1-thread-1] INFO com.flydean.SynchronousQueueUsage - produced java.lang.Object@683d1b4b [pool-1-thread-2] INFO com.flydean.SynchronousQueueUsage - consumed java.lang.Object@683d1b4b

可以看到傳入和輸出了同一個對象。

上面的例子我們也可以用SynchronousQueue來改寫:

@Testpublic void useSynchronousQueue() throws InterruptedException {ExecutorService executor = Executors.newFixedThreadPool(2);SynchronousQueue<Object> synchronousQueue=new SynchronousQueue<>();Runnable producer = () -> {Object object=new Object();try {synchronousQueue.put(object);} catch (InterruptedException ex) {log.error(ex.getMessage(),ex);}log.info("produced {}",object);};Runnable consumer = () -> {try {Object object = synchronousQueue.take();log.info("consumed {}",object);} catch (InterruptedException ex) {log.error(ex.getMessage(),ex);}};executor.submit(producer);executor.submit(consumer);executor.awaitTermination(50000, TimeUnit.MILLISECONDS);executor.shutdown();}

上面的例子中,如果我們使用synchronousQueue,則可以不用手動同步,也不需要額外的存儲。

總結

如果我們需要在代碼中用到這種線程中傳遞對象的情況,那么使用synchronousQueue吧。

本文的例子https://github.com/ddean2009/learn-java-collections

更多精彩內容且看:

  • 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

歡迎關注我的公眾號:程序那些事,更多精彩等著您!
更多內容請訪問 www.flydean.com

總結

以上是生活随笔為你收集整理的SynchronousQueue详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。