Java并发:我应该同步所有列表和地图吗?

时间:2012-03-14 03:38:14

标签: java concurrency

所以我有一个SomeTask课程extends Thread,并且有MapList个字段。如果不执行Collections.synchronizedXXX并且有多个SomeTask线程在运行,会出现什么行为?

一旦从数据库调用Map(我使用Object Database直接存储POJO),我是否还需要同步从该数据库返回的Map对象?

Map SomeTasksOwnMap = Collections.synchronizedMap(MapReturnedFromDatabase);

3 个答案:

答案 0 :(得分:1)

没有。您的问题中没有任何内容表明需要同步,因为据我所知,每个线程只读取其自身内的数据:当线程访问其他线程中的数据时,您只需要同步。

顺便说一下,让SomeTask extends Thread设计不佳 - 应该extends Runnable,然后使用new Thread(new SomeTask()).start()

答案 1 :(得分:1)

当2个或更多线程访问同一个Map / List时,

Collections.synchronizedXXX 是必需的。

如果您的任务没有访问其他任务Map / List,则无需同步它们。

实施例

  • 任务1构建一个由2精确整除的数字列表。
  • 任务2构建一个由3精确整除的数字列表。

这两个任务具有不需要同步的单个列表。

示例需要同步。

  • 任务1和2都计算数字并将它们存储在共享列表中。

要回答这些问题:“当你不这样做时会有什么行为”,如果两个线程想要写入索引'x',那么你可能会丢失其中一个写入。

在写入位置之前,由于数组的大小已增加,因此列表中也可能包含空值。

基本上你会有不一致的观点。

答案 2 :(得分:0)

  

...我应该同步所有列表和地图吗?

不,你不应该。同步不需要它的东西是浪费资源。对于需要同步的事情,您需要以正确的方式执行。 (并且synchronizedXxx包装器并不总是正确的方式。)

首先,您需要确定多个线程可见的数据结构。可证明线程受限的数据结构根本不需要同步。

其次,您需要检查数据结构的使用方式,以查看synchronizedXxx包装器是否足够。例如,这些包装器不会同步迭代,如果一个线程更改了一个集合而另一个线程正在迭代它,则会遇到麻烦。

最后,您需要考虑同步数据结构是否被不同的线程大量使用。如果大量使用数据结构,synchronzedXxx包装器可能会导致性能瓶颈。如果是这种情况,您应该考虑使用其中一个ConcurrentYyyy类。