Java:在访问非同步类的多个线程之间创建一个中间人类?

时间:2012-03-14 04:16:42

标签: java concurrency

从这个问题中获取线索Multithreaded access to file

我的方案是我有一个电子表格组件,其中多个线程将访问并写入每个工作簿。组件本身不是线程安全的,所以我认为当一个线程正在写入它时,其他线程需要被阻塞,直到第一个完成写入?当我处理非线程安全类时,我将如何实现这一目标?将写入方法放在同步块中?

这引起的另一个问题是,如果一个线程忙于将长行数据写入其相应的工作簿,那么另一个线程必须在其轨道中停止,直到第一个线程完成为止,这是不可取的。 / p> 相反,我想象一个场景,每个线程在没有相互阻塞的情况下运行,但是写入电子表格的数据是由另一个中间人类完成的,该类将缓冲并将数据刷新到电子表格组件上,而不会导致多个线程“等待”直到他们的写作过程完成了。

基本上每个线程都会自己做两件事。 1)执行来自每个相应源的数据的长时间运行处理,2)将处理数据写入电子表格。我正在寻求一种并发解决方案,其中1)由于2)而没有“等待”。

1 个答案:

答案 0 :(得分:1)

最佳解决方案实际上取决于您在电子表格中执行的操作类型。例如,如果一个线程需要读取另一个线程写入的值,那么可能需要一次锁定整个电子表格或至少锁定特定行。由于电子表格本身不是线程安全的,因此您需要自己进行同步。

如果序列化所有访问(这会损害性能,因为它摆脱了并行性)很重要,请考虑使用线程安全队列,其中每个线程将一个对象添加到队列中,表示它想要执行的操作。然后你可以让一个工作线程从队列中拉出项目(再次,以线程安全的方式,因为队列是线程安全的)并执行操作。

这里可能有空间来并行化队列工作者,因为它们可以相互通信,并在它们之间进行一些基于行的锁定。例如,如果第一个操作是读取行1-4并写入第5行,第二个操作是读取第6-10行并写入第11行,那么它们应该能够并行执行。但请注意,因为它可能取决于电子表格的基础结构,您认为它不是线程安全的。尽管如此,读取可能并行执行。

虽然非常重要,同步对队列的访问是基本的读者 - 编写者问题,虽然你必须确保避免饥饿和死锁,但是比随机访问电子表格要容易得多。

尽管如此,最好的解决方案是使用线程安全的电子表格,或者只使用一个线程来访问它。为什么不使用支持数据库的电子表格,然后让多个线程一次读/写数据库呢?