2

我打算在生产者和消费者线程之间编写一个共享缓冲区。这是我的代码:

class PQueue
{
    Token token;
    boolean flag = false;   // false: add, true: poll

    PQueue()
    {
        token = null;
    }

    synchronized void add(Token token)
    {
        if(flag == true)
        {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        flag = true;
        notify();
        this.token = token;
    }

    synchronized Token poll()
    {
        if(flag == false)
        {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        flag = false;
        notify();
        return this.token;
    }
}

我是多线程的新手。是否有任何潜在的并发错误?这是实现这一目标的“标准/通用”方式吗?或者有没有更简单、更有效的方法?

4

2 回答 2

3

看一下java.util.concurrent包,特别是BlockingQueue接口和实现它的类。这些用于将消息从一个线程传递到另一个线程。这SynchronousQueue正是您要实施的。

您自己的实现有一些缺陷。一方面,应该声明两个共享变量volatile以确保一个线程上的更改被另一个线程看到。而且您的if (flag == false)if (flag == true)测试实际上应该是while循环,因为实际上没有被调用时wait()可能会虚假地唤醒。notify()

我建议不要使用单独的标志变量,而是将令牌设置为 null 以指示没有对象。而不是捕捉、打印和盲目地继续面对InterruptedException,我建议让这两种方法都在发生异常时抛出该异常。这些是阻塞方法,调用者有责任处理阻塞方法被中断的可能性。

另外,我不知道您的Token课程是什么,但您的队列中的任何内容实际上都取决于它的类型。定义一个 generic 会更有意义PQueue<T>,然后PQueue<Token>在你想传递令牌时使用。

于 2012-08-14T05:34:51.577 回答
1

1.尝试使用Package中的thread-safe类和接口。java.util.concurrent

2.BlockingQueue Interface一起使用ArrayBlockingQueue Class

于 2012-08-14T05:36:11.597 回答