[英]Not getting expected output multi threaded blocking queue
我們正在嘗試在多線程環境中從阻塞隊列中獲取數據。
正如我們所知,阻塞隊列是線程安全的,並且以 FIFO 方式從阻塞隊列中獲取數據。 但沒有得到預期的 output。
請找到以下程序以供參考
package com.example.demo;
class PriceTask implements Runnable {
@Override
public void run() {
while (true) {
try {
String data = QueueData.bq.take();
System.out.println(data);
} catch (Exception ex) {
}
}
}
}
public class SimpleTestDemo {
public static void main(String[] args) throws Exception {
QueueData obj1 = new QueueData();
obj1.m1();
Thread t1 = new Thread(new PriceTask(), "T1");
Thread t2 = new Thread(new PriceTask(), "T2");
t1.start();
t2.start();
}
}
package com.example.demo;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class QueueData {
public static final BlockingQueue<String> bq = new LinkedBlockingQueue<String>();
public void m1() throws InterruptedException {
bq.put("Data--01");
bq.put("Data--02");
bq.put("Data--03");
bq.put("Data--04");
bq.put("Data--05");
bq.put("Data--06");
bq.put("Data--07");
bq.put("Data--08");
bq.put("Data--09");
bq.put("Data--10");
}
}
獲取 output 如下
Data--01
Data--03
Data--04
Data--05
Data--06
Data--07
Data--08
Data--09
Data--10
Data--02
預計 output
Data--01
Data--02
Data--03
Data--04
Data--05
Data--06
Data--07
Data--08
Data--09
Data--10
雖然take
方法是阻塞的,但PriceTask
中的循環體不是原子的。 換句話說,雖然數據是按順序獲取的,但不能保證在從隊列中檢索到一個項目后不會發生上下文切換,並且可能會在當前項目之前檢索並打印另一個項目。
保證項目確實按順序打印的一種方法是同步循環體。 例如:
class PriceTask implements Runnable {
@Override
public void run() {
while (true) {
try {
synchronized (PriceTask.class) {
String data = QueueData.bq.take();
System.out.println(data);
}
} catch (Exception ex) {
}
}
}
您正在使用多線程 PriceTask 從同一個隊列中讀取數據,但希望對數據進行順序處理。 這是矛盾的。 如果你想要順序處理,那么有一個單線程 PriceTask。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.