0

我对 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;
}

消费类 Airline 将接收航班状态的每一次变化,并打印出来:

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?

4

2 回答 2

2
while (f.state != "AG") { bqueue.put(produce()); }

while (!bqueue.isEmpty()) { consume(bqueue.take());}

我怀疑你的两个while条件都不是你想要的:第一个应该.equals()用于字符串比较。第二个假设消费者将在生产者之后执行(并且消费者比生产者);否则消费者会发现队列为空并跳过整个循环。

于 2013-02-21T23:09:14.027 回答
2

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

除了上述之外,这个答案对于您的 while 循环中的条件问题也是正确的。

于 2013-02-21T23:12:04.530 回答