JDK7中TransferQueue的使用以及TransferQueue與SynchronousQueue的差別

来源:http://www.cnblogs.com/wangzhongqiu/archive/2017/02/25/6441703.html
-Advertisement-
Play Games

轉自:http://blog.csdn.net/aitangyong/article/details/46472643 JDK7對JDK5中的J.U.C併發工具進行了增強,其中之一就是新增了TransferQueue。Java併發相關的JSR規範,可以查看Doug Lea維護的blog。現在簡單介紹 ...


轉自:http://blog.csdn.net/aitangyong/article/details/46472643

JDK7對JDK5中的J.U.C併發工具進行了增強,其中之一就是新增了TransferQueue。Java併發相關的JSR規範,可以查看Doug Lea維護的blog。現在簡單介紹下這個類的使用方式。

 

[java] view plain copy  
  1. public interface TransferQueue<E> extends BlockingQueue<E>  
  2. {  
  3.     /** 
  4.      * Transfers the element to a waiting consumer immediately, if possible. 
  5.      * 
  6.      * <p>More precisely, transfers the specified element immediately 
  7.      * if there exists a consumer already waiting to receive it (in 
  8.      * {@link #take} or timed {@link #poll(long,TimeUnit) poll}), 
  9.      * otherwise returning {@code false} without enqueuing the element. 
  10.      * 
  11.      * @param e the element to transfer 
  12.      * @return {@code true} if the element was transferred, else 
  13.      *         {@code false} 
  14.      * @throws ClassCastException if the class of the specified element 
  15.      *         prevents it from being added to this queue 
  16.      * @throws NullPointerException if the specified element is null 
  17.      * @throws IllegalArgumentException if some property of the specified 
  18.      *         element prevents it from being added to this queue 
  19.      */  
  20.     boolean tryTransfer(E e);  
  21.   
  22.     /** 
  23.      * Transfers the element to a consumer, waiting if necessary to do so. 
  24.      * 
  25.      * <p>More precisely, transfers the specified element immediately 
  26.      * if there exists a consumer already waiting to receive it (in 
  27.      * {@link #take} or timed {@link #poll(long,TimeUnit) poll}), 
  28.      * else waits until the element is received by a consumer. 
  29.      * 
  30.      * @param e the element to transfer 
  31.      * @throws InterruptedException if interrupted while waiting, 
  32.      *         in which case the element is not left enqueued 
  33.      * @throws ClassCastException if the class of the specified element 
  34.      *         prevents it from being added to this queue 
  35.      * @throws NullPointerException if the specified element is null 
  36.      * @throws IllegalArgumentException if some property of the specified 
  37.      *         element prevents it from being added to this queue 
  38.      */  
  39.     void transfer(E e) throws InterruptedException;  
  40.   
  41.     /** 
  42.      * Transfers the element to a consumer if it is possible to do so 
  43.      * before the timeout elapses. 
  44.      * 
  45.      * <p>More precisely, transfers the specified element immediately 
  46.      * if there exists a consumer already waiting to receive it (in 
  47.      * {@link #take} or timed {@link #poll(long,TimeUnit) poll}), 
  48.      * else waits until the element is received by a consumer, 
  49.      * returning {@code false} if the specified wait time elapses 
  50.      * before the element can be transferred. 
  51.      * 
  52.      * @param e the element to transfer 
  53.      * @param timeout how long to wait before giving up, in units of 
  54.      *        {@code unit} 
  55.      * @param unit a {@code TimeUnit} determining how to interpret the 
  56.      *        {@code timeout} parameter 
  57.      * @return {@code true} if successful, or {@code false} if 
  58.      *         the specified waiting time elapses before completion, 
  59.      *         in which case the element is not left enqueued 
  60.      * @throws InterruptedException if interrupted while waiting, 
  61.      *         in which case the element is not left enqueued 
  62.      * @throws ClassCastException if the class of the specified element 
  63.      *         prevents it from being added to this queue 
  64.      * @throws NullPointerException if the specified element is null 
  65.      * @throws IllegalArgumentException if some property of the specified 
  66.      *         element prevents it from being added to this queue 
  67.      */  
  68.     boolean tryTransfer(E e, long timeout, TimeUnit unit)  
  69.         throws InterruptedException;  
  70.   
  71.     /** 
  72.      * Returns {@code true} if there is at least one consumer waiting 
  73.      * to receive an element via {@link #take} or 
  74.      * timed {@link #poll(long,TimeUnit) poll}. 
  75.      * The return value represents a momentary state of affairs. 
  76.      * 
  77.      * @return {@code true} if there is at least one waiting consumer 
  78.      */  
  79.     boolean hasWaitingConsumer();  
  80.   
  81.     /** 
  82.      * Returns an estimate of the number of consumers waiting to 
  83.      * receive elements via {@link #take} or timed 
  84.      * {@link #poll(long,TimeUnit) poll}.  The return value is an 
  85.      * approximation of a momentary state of affairs, that may be 
  86.      * inaccurate if consumers have completed or given up waiting. 
  87.      * The value may be useful for monitoring and heuristics, but 
  88.      * not for synchronization control.  Implementations of this 
  89.      * method are likely to be noticeably slower than those for 
  90.      * {@link #hasWaitingConsumer}. 
  91.      * 
  92.      * @return the number of consumers waiting to receive elements 
  93.      */  
  94.     int getWaitingConsumerCount();  
  95. }  

可以看到TransferQueue同時也是一個阻塞隊列,它具備阻塞隊列的所有特性,主要介紹下上面5個新增API的作用。

 

1.transfer(E e)若當前存在一個正在等待獲取的消費者線程,即立刻將e移交之;否則將元素e插入到隊列尾部,並且當前線程進入阻塞狀態,直到有消費者線程取走該元素。

 

[java] view plain copy  
  1. public class TransferQueueDemo {  
  2.   
  3.     private static TransferQueue<String> queue = new LinkedTransferQueue<String>();  
  4.   
  5.     public static void main(String[] args) throws Exception {  
  6.   
  7.         new Productor(1).start();  
  8.   
  9.         Thread.sleep(100);  
  10.   
  11.         System.out.println("over.size=" + queue.size());  
  12.     }  
  13.   
  14.     static class Productor extends Thread {  
  15.         private int id;  
  16.   
  17.         public Productor(int id) {  
  18.             this.id = id;  
  19.         }  
  20.   
  21.         @Override  
  22.         public void run() {  
  23.             try {  
  24.                 String result = "id=" + this.id;  
  25.                 System.out.println("begin to produce." + result);  
  26.                 queue.transfer(result);  
  27.                 System.out.println("success to produce." + result);  
  28.             } catch (InterruptedException e) {  
  29.                 e.printStackTrace();  
  30.             }  
  31.         }  
  32.     }  
  33. }  

可以看到生產者線程會阻塞,因為調用transfer()的時候並沒有消費者在等待獲取數據。隊列長度變成了1,說明元素e沒有移交成功的時候,會被插入到阻塞隊列的尾部。

 

2.tryTransfer(E e)若當前存在一個正在等待獲取的消費者線程,則該方法會即刻轉移e,並返回true;若不存在則返回false,但是並不會將e插入到隊列中。這個方法不會阻塞當前線程,要麼快速返回true,要麼快速返回false。

3.hasWaitingConsumer()和getWaitingConsumerCount()用來判斷當前正在等待消費的消費者線程個數。

 

4.tryTransfer(E e, long timeout, TimeUnit unit) 若當前存在一個正在等待獲取的消費者線程,會立即傳輸給它; 否則將元素e插入到隊列尾部,並且等待被消費者線程獲取消費掉。若在指定的時間內元素e無法被消費者線程獲取,則返回false,同時該元素從隊列中移除。

 

[java] view plain copy    在CODE上查看代碼片派生到我的代碼片
  1. public class TransferQueueDemo {  
  2.   
  3.     private static TransferQueue<String> queue = new LinkedTransferQueue<String>();  
  4.   
  5.     public static void main(String[] args) throws Exception {  
  6.   
  7.         new Productor(1).start();  
  8.   
  9.         Thread.sleep(100);  
  10.   
  11.         System.out.println("over.size=" + queue.size());//1  
  12.           
  13.         Thread.sleep(1500);  
  14.   
  15.         System.out.println("over.size=" + queue.size());//0  
  16.     }  
  17.   
  18.     static class Productor extends Thread {  
  19.         private int id;  
  20.   
  21.         public Productor(int id) {  
  22.             this.id = id;  
  23.         }  
  24.   
  25.         @Override  
  26.         public void run() {  
  27.             try {  
  28.                 String result = "id=" + this.id;  
  29.                 System.out.println("begin to produce." + result);  
  30.                 queue.tryTransfer(result, 1, TimeUnit.SECONDS);  
  31.                 System.out.println("success to produce." + result);  
  32.             } catch (Exception e) {  
  33.                 e.printStackTrace();  
  34.             }  
  35.         }  
  36.     }  
  37. }  

第一次還沒到指定的時間,元素被插入到隊列中了,所有隊列長度是1;第二次指定的時間片耗盡,元素從隊列中移除了,所以隊列長度是0。

 

 

這篇文章中講了SynchronousQueue的使用方式,可以看到TransferQueue也具有SynchronousQueue的所有功能,但是TransferQueue的功能更強大。這篇文章中提到了這2個API的區別:

 

[plain] view plain copy    在CODE上查看代碼片派生到我的代碼片
  1. TransferQueue is more generic and useful than SynchronousQueue however as it allows you to flexibly decide whether to use normal BlockingQueue   
  2. semantics or a guaranteed hand-off. In the case where items are already in the queue, calling transfer will guarantee that all existing queue   
  3. items will be processed before the transferred item.  
  4.   
  5.   
  6. SynchronousQueue implementation uses dual queues (for waiting producers and waiting consumers) and protects both queues with a single lock. The  
  7.  LinkedTransferQueue implementation uses CAS operations to form a nonblocking implementation and that is at the heart of avoiding serialization  
  8.  bottlenecks.  

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 隱藏細節 現實生活中有很多隱藏細節的案例,比如我們平時用的電腦,當我們按電源按鈕後電腦就自動開始啟動了,對用戶來講很簡單隻需要知道按按鈕就行。但電腦內部的工作原理其實是很複雜的一個流程,這裡不多說。 如果不隱藏細節會怎樣? 我想可能的結果就是電腦只能是特別特別的專業人員才能操作,永遠無法像現在一樣成 ...
  • Hibernate學習筆記1 本筆記學習自 "Hibernate官方文檔" 。 1. Architecture(總體結構) 俗話說有圖有真相,先看一張圖: 上圖清楚地描述了Hibernate在一個Java應用中所處的位置:位於 Data Access Layer(數據訪問層) 和 Relation ...
  • PHP 中 include 與 require Php include (或 require)語句會獲取指定文件中存在的所有文本/代碼/標記,並複製到使用 include 語句的文件中。 這意味著您可以為所有頁面創建標準頁頭、頁腳或者菜單文件。然後,在頁頭需要更新時,您只需更新這個頁頭包含文件即可。 ...
  • (原創,未經允許不得轉載) 經典的八皇後問題 題目: 八皇後問題就是在8*8的棋盤上放置8個皇後,使其任意兩個不在同一行、同一列、同一斜線上。 解題思路: 去掉行這個因素,然後去考慮是否在同一列或同一斜線上。每個擺放成功的棋子在(i,x[i]),然後設置當前行,然後在該行從第一列一直試探到第8列,看 ...
  • 一、Solr官網下載http://lucene.apache.org/solr/下載Solr項目文件 在該項目文件中,可以找到我們在本地環境下運行Solr伺服器所需要的資源文件,在這裡我們以4.10.3為例, 在dist目錄下我們可以得到solr-4.10.3.war文件,該war包目前在Tomca ...
  • 第一章總結: 1.java的是sun公司(現甲骨文有限公司)於1995年推出的高級編程語言,java技術可以應用在幾乎所有類型和規模的設備上,小到電腦晶元、蜂窩電話,大到超級電腦,無所不在。 2.在當前的軟體開發行業中,java已經成為了絕對的主流,java領域的java SE、java EE已 ...
  • 上節聊完了PHP官方的相關代碼規範,下麵給大家帶來了PHP系列的PHP推薦標準的另外兩個,PSR-3,PSR-4。 首先,我們先來瞭解下PSR-3是怎麼回事。 PHP-FIG發佈的第三個推薦規範與前兩個不同,不是一系列的指導方針,而是一個介面,規定PHP日誌記錄器組件可以實現的方法。 基礎 The  ...
  • 1.臨時空間給了個1024,不需要可減少長度。 2.結果只用用strcpy了,沒校驗。 bool Replace(char *str,const char *src, const char *des){ /* old -> new */ int srclen = strlen(src); int d ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...