繁体   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