2014-09-13 105 views
0

我正在学习多线程,并且有一个小问题。 当我在线程之间共享某个变量(ArrayList,或其他像double,float)时,它是否应该由读/写中的同一个对象来提取?我的意思是,当1个线程设置变量值时,是否可以同时读取任何问题?还是应该被相同的对象锁定,并强制线程等待阅读,直到它被另一个线程更改?Java。读,写,单独同步

+0

ArrayList不同步。所以,如果有多个线程写入它将会出现问题。此外,每个线程不保证最新值。 – TheLostMind 2014-09-13 13:57:03

+0

您可以检查集合的线程安全版本,例如ConcurrentSet,ConcurrentMap或CopyOnWriteArrayList。 – px5x2 2014-09-13 13:59:46

+0

我推荐阅读:http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html我相信很多即将到来的问题也会在那里得到解答。 – Fildor 2014-09-13 14:05:51

回答

1

对共享状态的所有访问必须由相同的锁保护,无论是读取还是写入。读操作必须等待写操作释放锁。作为一种特殊情况,如果您想要在同步块内完成一次读取或写入操作,那么您可以省去同步块并将该变量标记为易失性。

0

短:这取决于。

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

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

TL;博士

例如,不是所有的线程编程需“总是正确的”

  • 有时你权衡正确性与性能(例如日志或进度计数器)
  • 有时读取旧值就好了
  • 有时您最终需要更正(例如,在map-reduce中,没有人或同步是正确的,直到全部完成)
  • 在某些情况下,每个时刻(例如,您的银行账户余额)
  • 只写一次,只读不要紧。
  • 某些时候线程在复杂情况下。
  • 有时许多小的,独立的锁跑的快,但有时平坦全球锁更快
  • 和许多许多其他可能的情况下

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

0

如果所有线程正在读取,则不需要同步。

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

如果你有一个庞大的收藏,你想允许共享阅读,但独家写作,你需要使用ReadWriteLock。在这里看到的JavaDoc和你想的例子是什么确切的描述:

ReentrantReadWriteLock

注意,这个问题是很常见的,有很多关于这个站点类似的例子。