2

在我的小型应用程序中,我有两个类的线程——基本上是作者和读者。可以将多个读取器分配给单个写入器。作家通过写入他们的chunkBuffer变量来与读者互动。

现在,我不能完全解决这里的线程安全问题:如果我不将 存储chunkBuffer在静态ThreadLocal变量中,所有阅读器将共享一个 chunkBuffer,这很糟糕。但是,如果我确实将 chunkBuffer 存储在 static 中ThreadLocal,作为单独线程的 writer 将获得自己的 chunkBuffer 副本并将继续写入它,而它写入的任何数据都不会到达读者。你能解释一下这里有什么问题吗?非常感谢。

编辑换句话说,有没有一种方法可以创建一个字段,该字段对于线程子类的每个实例(如 ThreadLocal)都是唯一的,但可以根据需要从其他线程访问?

4

2 回答 2

2

没有。

ThreadLocal 用于线程私有数据。在您的情况下,您需要对象进行通信,因此您需要其他类型的对象。

我认为最好使用的结构是同步队列:java.util.concurrent.LinkedBlockingQueue<E>.

队列允许生产者插入数据和消费者从中消费。如果它是同步的,它允许在不破坏结构的情况下从不同的线程进行。

您可以在相关的作者/读者之间共享一个队列:

Writer 1 -> queue 1 -> [readers A/B/C]

Writer 2 -> queue 2 -> [readers D/E/F]

每个作家和读者都会有自己的线索。如果没有项目,每个阅读器将尝试从其队列阻塞中取出一个项目。如果您需要更明智地管理您的读者,您可以尝试更复杂的方法,但我认为这是一个很好的起点。

于 2011-04-27T10:49:30.367 回答
0

我认为您不想使用 ThreadLocal 变量。你真的需要一个通知机制。

Writer 执行以下操作:

  1. 写给读者的chunkBuffer
  2. 通知读者新数据。

在 Java 并发方面有很多方法可以做到这一点,但通常最简单和最安全的是使用ArrayBlockingQueue. 在您的用例中,听起来每个 Reader 都有自己的ArrayBlockingQueue,它只需要从队列中读取。

当然,这取决于您的用例。是否有必要始终处理最新数据,还是需要处理每次写入chunkBuffer?这些问题对于确定您需要哪种机制是必要的。

注意:@helios 提到同步队列的道具,希望我的回答能增加价值。

于 2011-04-27T11:03:30.087 回答