如何在Java线程之间实现共享缓冲区?

时间:2012-08-14 05:21:31

标签: java multithreading shared producer-consumer

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

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

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

2 个答案:

答案 0 :(得分:3)

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

您自己的实施有一些缺陷。例如,两个共享变量都应声明为volatile,以确保另一个线程看到一个线程的更改。您的if (flag == false)if (flag == true)测试实际上应该是while个循环,因为wait()notify()实际上没有被调用时可以wake up spuriously。 / p>

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

另外,我不知道你的Token类是什么,但队列中的任何内容实际上都取决于它的类型。定义通用PQueue<T>更有意义,如果要传递令牌,则使用PQueue<Token>

答案 1 :(得分:1)

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

2。使用BlockingQueue InterfaceArrayBlockingQueue Class

相关问题