简体   繁体   English

没有得到预期 output 多线程阻塞队列

[英]Not getting expected output multi threaded blocking queue

We are trying take data from blocking queue in multi threaded environment.我们正在尝试在多线程环境中从阻塞队列中获取数据。

As we know blocking queue is thread safe and take data from blocking queue in FIFO manner.正如我们所知,阻塞队列是线程安全的,并且以 FIFO 方式从阻塞队列中获取数据。 But not getting expected output.但没有得到预期的 output。

Please find below program for reference请找到以下程序以供参考

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");
    }
}

Getting output as below获取 output 如下

Data--01
Data--03
Data--04
Data--05
Data--06
Data--07
Data--08
Data--09
Data--10
Data--02

Expected output预计 output

Data--01
Data--02
Data--03
Data--04
Data--05
Data--06
Data--07
Data--08
Data--09
Data--10

While the take method is blocking, the body of the loop in your PriceTask is not atomic.虽然take方法是阻塞的,但PriceTask中的循环体不是原子的。 In other words, while data is taken in order, there's no guarantee that after an item is retrieved from the queue there won't be a context switch, and another item may be retrieved and printed before the current item.换句话说,虽然数据是按顺序获取的,但不能保证在从队列中检索到一个项目后不会发生上下文切换,并且可能会在当前项目之前检索并打印另一个项目。

One way to gaurantee the items are indeed printed in order is to synchronize the body of the loop.保证项目确实按顺序打印的一种方法是同步循环体。 Eg:例如:

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) {
        }
    }
}

You are having multi threaded PriceTask to read from same queue but expecting sequential processing of data.您正在使用多线程 PriceTask 从同一个队列中读取数据,但希望对数据进行顺序处理。 This is contradictory.这是矛盾的。 If you want sequential processing then have a single thread PriceTask.如果你想要顺序处理,那么有一个单线程 PriceTask。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM