La-*_*eja 7 java multithreading synchronization atomic hashmap
我将Java Map声明为
Map<String, String> map = Collections.synchronizedMap(new HashMap<String, String>());
Run Code Online (Sandbox Code Playgroud)
处理并发问题,并在地图上同步其上的所有操作.但是,我读到synchronizedMap
在操作是原子的时候不需要同步.我检查了Java API,HashMap的文档似乎没有提到哪些是原子的,所以我不确定是哪些.
我正在同步以下对地图的调用:
map.size()
map.put()
map.remove()
map.get()
Run Code Online (Sandbox Code Playgroud)
但如果有些是原子的,那么似乎并不需要同步.哪个是原子的?
cia*_*mej 11
顾名思义的同步映射是同步的.对其上的任何其他操作而言,其上的每个操作都是原子的.
您可以将其视为同步映射的每个方法都使用synchronized
关键字声明.
请记住,虽然单个操作是原子操作,但如果将它们组合起来,它们就不再是原子操作,例如:
String value = map.get("key");
map.put("key", value+"2");
Run Code Online (Sandbox Code Playgroud)
不等于您的自定义同步代码:
synchronized (map) {
String value = map.get("key");
map.put("key", value+"2");
}
Run Code Online (Sandbox Code Playgroud)
反而:
synchronized (map) {
String value = map.get("key");
}
synchronized (map) {
map.put("key", value+"2");
}
Run Code Online (Sandbox Code Playgroud)
A HashMap
不保证具有原子操作.从不同的线程(偶数size()
)调用其任何方法可能会破坏映射.但是,使用Collections.synchronizedMap
will 获得的映射会使每个调用同步(因此是线程安全的).
但是,您可能需要更高级别的同步.例如,如果您测试是否存在密钥,读取大小,或以其他方式从地图访问某些内容,然后根据结果对地图执行其他操作,则地图可能在两次调用之间发生了更改.在这种情况下,您需要一个synchronized
块来使整个事务成为原子,而不是同步映射(这只会使每个调用成为原子).
归档时间: |
|
查看次数: |
8263 次 |
最近记录: |