我正在使用JDK 1.4 ...所以我无法访问1.5+中的好并发内容.
考虑以下类片段:
private Map map = Collections.EMPTY_MAP;
public Map getMap() {
return map;
}
public synchronized void updateMap(Object key, Object value) {
Map newMap = new HashMap(map);
newMap.put(key, value);
map = Collections.unmodifiableMap(newMap);
}
Run Code Online (Sandbox Code Playgroud)
是否有必要同步(或挥发)地图引用,因为我将只允许通过updateMap方法(已同步)更新地图?
将在多个线程中访问(读取)map对象,尤其是通过Iterators.知道迭代器会在后端地图的结构发生变化时抛出异常,我想我会使地图不可修改.因此,当我通过updateMap更改地图的结构时,现有的迭代器将继续处理"旧"地图(这对我来说很好).
副作用是,我不必担心同步读取.在本质上,与写入相比,我将具有更大的读取幅度.当前正在迭代地图对象的线程将继续这样做,任何启动的新线程都将获取最新的地图.(好吧,我假设它会在这里考虑erickson的评论 - Java并发场景 - 我是否需要同步?)
有人可以评论这个想法是否合适吗?
谢谢!
您应该使用volatile关键字,以确保线程将看到最新Map版本.否则,如果没有同步,则无法保证其他线程除了空映射外都会看到任何内容.
由于您updateMap()已同步,因此每次访问它都会看到最新值map.因此,您不会丢失任何更新.这是有保证的.但是,因为你的getMap()不同步而map不是volatile,也不能保证一个线程将看到最新的值map,除非该线程本身是最近的线程来更新地图.使用volatile会解决这个问题.
但是,您也可以访问的Java 1.5和1.6并发补充.存在一个后端口.我强烈建议使用backport,因为当您能够迁移到更高版本的JDK时,它将允许轻松迁移到JDK并发类,并且它允许比您的方法更高的性能.(虽然如果您的更新map很少见,那么您的表现应该没问题.)
| 归档时间: |
|
| 查看次数: |
749 次 |
| 最近记录: |