5

在我发现的一些 android 开源代码中

 private Map<ImageView, String> imageViews=Collections.synchronizedMap(new
 WeakHashMap<ImageView, String>());

Map谁能解释一下正常和正常之间的区别collections.synchronizedmap

4

7 回答 7

2

java.util 包中的常规 Map 实现不是线程安全的。这意味着如果多个线程在同一个 Map 上做get()put()操作,可能会导致 Map 中出现竞争条件或不一致的数据。

要在多线程环境中使用现有 Map,您可以通过调用Collections.synchronizedMap(). 在这种情况下,大多数方法get(),如putkeyset()是同步的,可以安全地并发使用。
有关这方面的更多信息,请参阅 http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap(java.util.Map )

于 2013-01-22T06:47:26.273 回答
1

没有法线地图。您不能只创建一个 Map(new Map() 不会编译)。Map 是访问不同类型映射(hashMap、synchronizedMap、WeakHashMap...)中数据的通用接口。阅读任何 Java 书籍,集合章节。

使用 Map 作为通用接口允许您编写适用于所有类型 Map 实现的数据操作算法。所以你可以切换实现(也许你意识到你需要同步映射,而不仅仅是 HashMap),你的代码就可以工作了。

synchronizedMap 只是一个包装器。它封装了底层 Map 的所有数据访问函数并使其成为线程安全的。

在您的情况下,您有 WeakHashMap ,它是“真实”地图。WeakHashMap 定义了 map 如何存储数据(它使用哈希作为键,使用弱引用作为值)。然后将其包装在 synchronizedMap 中,这使您的地图线程安全。

于 2013-01-22T06:38:18.130 回答
1

http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedCollection(java.util.Collection)

同步映射是线程安全的映射,这意味着读/写操作是线程安全的。

于 2013-01-22T06:40:15.867 回答
1

我们使用“同步”来确保两个并发执行的线程或进程不会同时执行程序的特定部分。

于 2013-01-22T06:40:55.260 回答
1

Collections.synchronizedMap几乎包装了您的 Map 对象,以便每次调用 map 方法都是同步的,这意味着一次只有一个线程可以更新或查询地图。

于 2013-01-22T06:41:33.847 回答
1

Collections.synchronizedMap()是实现线程安全的一种非常糟糕的方法。它对每种方法都有一个锁定,因此最多一个线程可以访问您的地图。它不支持作为比较和设置的原子操作。此外,您必须记住在迭代键/值时自己同步对象,否则它会失去所有的魔力。

看看ConcurrentHashMap,如果你需要一个线程安全的Map.

于 2013-01-22T06:41:44.257 回答
1

Collections实用程序类提供静态方法来创建线程安全的集合(List、Set、Queue、Map)。因此,要将任何线程不安全的集合转换为线程安全的集合;您在 Collections 上调用同步方法,然后将您的集合作为参数传递。

线程安全集合一次只能由一个线程访问。

网址:http ://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html

于 2013-01-22T06:42:24.787 回答