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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java中的SynchronousQueue示例–生产者使用者解决方案

發布時間:2023/12/3 java 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中的SynchronousQueue示例–生产者使用者解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SynchronousQueue是BlockingQueue的一種特殊類型,其中每個插入操作必須等待另一個線程進行相應的刪除操作,反之亦然。 當您在SynchronousQueue上調用put()方法時,它將阻塞,直到有另一個線程將該元素從Queue中取出為止。 同樣,如果一個線程嘗試刪除一個元素并且當前不存在任何元素,則該線程將被阻塞,直到另一個線程將一個元素放入隊列中為止。 您可以將SynchronousQueue與運行奧運火炬的運動員( 線程 )相關聯,使他們運行火炬(需要傳遞對象)并將其傳遞給在另一端等待的其他運動員。 如果您注意該名稱,您還將了解到它被命名為SynchronousQueue是有原因的,它將數據同步傳遞到其他線程。 它等待對方獲取數據,而不僅僅是放入數據并返回(異步操作)。 如果您熟悉CSP和Ada,那么您就會知道同步隊列類似于集合通道。 它們非常適合切換設計,在該設計中,在一個線程中運行的對象必須與在另一個線程中運行的對象同步,以便向其傳遞一些信息,事件或任務。 在早期的多線程教程中,我們學習了如何使用wait and notify和BlockingQueue解決生產者消費者問題,在本教程中,我們將學習如何使用同步隊列來實現生產者消費者設計模式 。 此類還支持用于訂購等待的生產者和使用者線程的可選公平性策略。 默認情況下,不保證此排序。 但是,將Fairness屬性設置為true構造的隊列將按FIFO順序授予線程訪問權限。

正如我之前說過的,沒有什么比生產者使用者問題更好地理解任何編程語言中的線程間通信了。 在生產者使用者問題中,一個線程充當產生事件或任務的生產者,而另一個線程充當使用者。 共享緩沖區用于將數據從生產者傳輸到消費者。 解決生產者使用者問題的困難在于邊緣情況,例如,如果緩沖區已滿,生產者必須等待,如果緩沖區為空,使用者線程必須等待。 后來一個很容易,因為阻塞隊列不僅提供緩沖區來存儲數據,而且還提供流控制來阻塞線程,如果緩沖區已滿,則調用put()方法(PRODUCER),如果阻塞為空,則阻塞線程將調用take()方法(CONSUMER) 。 在本教程中,我們將使用SynchronousQueue(一種零容量的特殊并發集合)解決相同的問題。

在下面的示例中,我們有兩個線程,分別名為PRODUCER和CONSUMER(您應始終命名線程,這是編寫并發應用程序的最佳實踐之一)。 第一線程,發布板球得分,第二線程正在消耗它。 板球比分不過是一個String對象。 如果您按原樣運行程序,則不會發現任何不同。 為了了解SynchronousQueue的工作原理以及如何解決生產者使用者問題 ,您需要在Eclipse中調試該程序,或者只是通過注釋consumer.start()來啟動生產者線程。 如果使用者線程未運行,則生產者將在以下位置阻塞
隊列。 put(event); 通話,您將不會看到[PRODUCER]發布的活動:四個。 發生這種情況是由于 SynchronousQueue,它確保線程插入數據將一直阻塞,直到有線程刪除該數據為止,反之亦然。 您可以通過注釋生產者來測試代碼的另一部分。 開始(); 并且僅啟動使用者線程。

import java.util.concurrent.SynchronousQueue;/*** Java Program to solve Producer Consumer problem using SynchronousQueue. A* call to put() will block until there is a corresponding thread to take() that* element.** @author Javin Paul*/ public class SynchronousQueueDemo{public static void main(String args[]) {final SynchronousQueue<String> queue = new SynchronousQueue<String>();Thread producer = new Thread("PRODUCER") {public void run() {String event = "FOUR";try {queue.put(event); // thread will block hereSystem.out.printf("[%s] published event : %s %n", Thread.currentThread().getName(), event);} catch (InterruptedException e) {e.printStackTrace();}}};producer.start(); // starting publisher threadThread consumer = new Thread("CONSUMER") {public void run() {try {String event = queue.take(); // thread will block hereSystem.out.printf("[%s] consumed event : %s %n", Thread.currentThread().getName(), event);} catch (InterruptedException e) {e.printStackTrace();}}};consumer.start(); // starting consumer thread}}Output: [CONSUMER] consumed event : FOUR [PRODUCER] published event : FOUR

如果您仔細發送了輸出,那么您會注意到事件的順序是相反的。 似乎[CONSUMER]線程正在消耗數據,甚至在[PRODUCER]線程產生數據之前。 發生這種情況是因為默認情況下,SynchronousQueue不保證任何順序,但是它具有公平性策略,如果將其設置為true,則可以按FIFO順序訪問線程。 您可以通過將true傳遞給SynchronousQueue的重載構造函數 (即新的SynchronousQueue(boolean fair))來啟用此公平性策略。

這是Java中此特殊阻塞隊列的一些重要屬性。 將數據從一個線程同步傳輸到另一個線程非常有用。 它沒有任何容量,只有在另一端有線程時才阻塞。

  • SynchronousQueue阻塞,直到另一個線程準備好接受該元素,一個線程正在嘗試放置該元素。
  • SynchronousQueue的容量為零。
  • SynchronousQueue用于實現直接切換的排隊策略,在該策略中,線程將切換到等待的線程,否則允許創建新線程,否則拒絕任務。
  • 此隊列不允許使用null元素,添加null元素將導致NullPointerException 。
  • 出于其他Collection方法(例如contains)的目的,SynchronousQueue充當空集合。
  • 您無法窺視同步隊列,因為僅當您嘗試刪除它時,該元素才存在。 同樣,您不能插入元素(使用任何方法),除非另一個線程試圖將其刪除。
  • 您無法在SynchronousQueue上進行迭代,因為沒有要進行迭代的內容。
  • 將公平性策略設置為true構造的SynchronousQueue授予線程按FIFO順序的訪問權限。
  • 這就是Java中的SynchronousQueue 。 我們已經看到了此特殊并發集合的某些特殊屬性,并學習了如何使用Java中的SynchronousQueue解決經典的生產者使用者問題。 順便說一下,隊列有點令人困惑,因為它沒有任何能力容納您的元素。 在有一個線程正在調用take()操作之前,對put()操作的調用不會完成。 最好是線程之間共享對象的集合點。 換句話說,它是一個實用程序,可以在Java中的兩個線程之間同步共享數據,這可能是更安全的wait和notify方法的替代方法。

    翻譯自: https://www.javacodegeeks.com/2014/06/synchronousqueue-example-in-java-producer-consumer-solution.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的Java中的SynchronousQueue示例–生产者使用者解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

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