簡體   English   中英

沒有得到預期 output 多線程阻塞隊列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM