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



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

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

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

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

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

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

另外,我不知道您的Token类是什么,但队列中的任何东西实际上都不取决于其类型。 定义一个泛型PQueue<T>更有意义,如果要传递令牌,请使用PQueue<Token>

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

2.BlockingQueue InterfaceArrayBlockingQueue Class一起使用。

最新更新