Java的。读,写,分开同步

时间:2014-09-13 13:54:56

标签: java multithreading synchronization thread-safety

我正在学习多线程,我有一个小问题。 当我在线程之间共享一些变量(ArrayList,或者像double,float这样的其他东西)时,它是否应该被读/写中的同一个对象lcoked?我的意思是,当1个线程设置变量值时,是否可以同时读取任何问题?或者它应该被同一个对象锁定,并强制线程等待读取,直到它被另一个线程更改?

3 个答案:

答案 0 :(得分:1)

所有对共享状态的访问必须由相同的锁保护,包括读取和写入。读操作必须等待写操作才能释放锁。

作为一种特殊情况,如果您在同步块中的所有内容完全相当于一个读取或写入操作,那么您可以省去同步块并将变量标记为易失性。

答案 1 :(得分:0)

简短:取决于。

长: 每种不同的场景都有许多“正确的答案”。 (这使编程变得有趣)

  • 要读取的值必须是“最新的”吗?
  • 要写的值是否让所有读者知道?
  • 如果有两个线程写,我应该注意任何竞争条件吗?
  • 如果读取旧/以前的值会有问题吗?
  • 什么是正确的行为?
  • 真的需要它才是正确的吗? (是的,有时你不关心好)

TL;博士

例如,并非所有线程编程都需要“始终正确”

  • 有时你会用性能来衡量正确性(例如日志或进度计数器)
  • 有时阅读旧价值就好了
  • 有时你需要最终纠正(例如在map-reduce中,没有人也没有同步是正确的,直到所有完成)
  • 在某些情况下,每时每刻都必须提供正确的信息(例如,您的银行帐户余额)
  • 在一次写入时,只读它没关系。
  • 有时复杂案例的群组中的线程。
  • 有时很多小的,独立的锁运行得更快,但有时平面全局锁更快
  • 以及许多其他可能的案例

这是我的建议:如果你正在学习,你应该说“为什么我需要锁?”和“为什么锁可以帮助在不同的情况下?” (不仅仅是来自教科书的给定样本),“如果失败,或者如果失去锁定会发生什么?”

答案 2 :(得分:0)

如果所有线程都在读取,则无需进行同步。

如果一个或多个线程正在读取并且一个或多个线程正在写入,则需要以某种方式进行同步。如果集合很小,您可以使用synchronized。您可以在集合的访问周围添加synchronized块,synchronized访问集合的方法或使用并发线程安全集合(例如,Vector)。

如果你有一个大型集合,并且你想允许共享阅读而是独家写作,你需要使用ReadWriteLock。请参阅此处了解JavaDoc以及您希望使用示例的详细说明:

ReentrantReadWriteLock

请注意,这个问题很常见,本网站上有很多类似的例子。