This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center
                            
                        
                    
                
                7年前关闭。
            
        

我是BlockingQueue概念的新手,给人的印象是它不需要使用wait()和notify()。我编写了以下代码作为线程同步的初步测试(为清楚起见,省略了一些代码):

q = new LinkedBlockingQueue<flight>();

generator = new EventGenerator(q,flight);
southwest = new Airline(q);

new Thread(generator).start();
new Thread(southwest).start();


与生产者类EventGenerator。 EventGenerator从初始状态(SC)出发经过所有状态,直到到达登机门AG:

import java.util.concurrent.BlockingQueue;

public class EventGenerator implements Runnable
{
private final BlockingQueue<flight> bqueue;
private final flight f;

EventGenerator(BlockingQueue<flight> q, flight f1)
{
    bqueue = q;
    f = f1;
}

public void run()
{
    try
    {
        while (f.state != "AG") { bqueue.put(produce()); }
    }
    catch (InterruptedException ex)
    {
        System.out.println(ex);
        System.exit(0);
    }
}

flight produce()
{
    if (f.state.equals("SC")){ f.state = "BD"; }
    else if (f.state.equals("BD")) { f.state = "LG"; }
    else if (f.state.equals("LG")) { f.state = "TO"; }
    else if (f.state.equals("TO")) { f.state = "LD"; }
    else if (f.state.equals("LD")) { f.state = "AG"; }

    return f;
}


消费类航空公司将接收航班状态的每项更改,并进行打印:

import java.util.concurrent.BlockingQueue;

public class Airline implements Runnable
{
    private final BlockingQueue<flight> bqueue;

    Airline(BlockingQueue<flight> q)
    {
        bqueue = q;
    }

public void run()
{
    try
    {
        while (!bqueue.isEmpty()) { consume(bqueue.take());}
    }
    catch (InterruptedException ex)
    {
        System.out.println(ex);
        System.exit(0);
    }
}

void consume(flight f)
{
    System.out.println("Flight no. " + f.flightno + " is now in state " + f.state);
}
}


该项目编译并运行没有错误。但是,我期望(并希望)结果达到以下目的:

Flight no. 1 is now in state SC
Flight no. 1 is now in state BD
Flight no. 1 is now in state LG
Flight no. 1 is now in state TO
Flight no. 1 is now in state LD
Flight no. 1 is now in state AG


但是,相反,我几乎总是得到:

Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG
Flight no. 1 is now in state AG


我是否错误地实现了BlockingQueue?

最佳答案

您目前遇到的问题实际上是produce方法。您正在更改同一对象的状态,并将其多次放置在队列中。您实际上想要做的是将修改后的副本放入队列。如果您的Flight对象是不可变的,那么您将不会遇到此问题。

除上述以外,this answer对于while循环中的条件问题也很正确。

关于java - Java中与BlockingQueue进行线程同步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15013856/

10-10 13:38