小编Hol*_*ger的帖子

将putIfAbsent与ConcurrentMap结合使用

我有一个必须使用的用例

  • 如果ConcurrentHashMap中不存在该键,则插入一个新值
  • 如果密钥已经存在于ConcurrentHashMap中,则将旧值替换为新值,其中新值是从旧值派生的(不是昂贵的操作)

我提供以下代码:

public void insertOrReplace(String key, String value) {
        boolean updated = false;
        do {
            String oldValue = concurrentMap.get(key);
            if (oldValue == null) {
                oldValue = concurrentMap.putIfAbsent(key, value);
                if (oldValue == null) {
                    updated = true;
                }
            }
            if (oldValue != null) {
                final String newValue = recalculateNewValue(oldValue, value);
                updated = concurrentMap.replace(key, oldValue, newValue);
            }
        } while (!updated);
    }
Run Code Online (Sandbox Code Playgroud)

你认为它是正确的和线程安全的吗?

有更简单的方法吗?

java concurrency synchronization concurrenthashmap

17
推荐指数
1
解决办法
4136
查看次数

线程安全的 CopyOnWriteArrayList 反向迭代

考虑以下代码片段:

private List<Listener<E>> listenerList = new CopyOnWriteArrayList<Listener<E>>();

public void addListener(Listener<E> listener) {
    if (listener != null) {
        listenerList.add(listener);
    }
}

public void removeListener(Listener<E> listener) {
    if (listener != null) {
        listenerList.remove(listener);
    }
}

protected final void fireChangedForward(Event<E> event) {
    for (Listener<E> listener : listenerList) {
        listener.changed(event);
    }
}

protected final void fireChangedReversed(Event<E> event) {
    final ListIterator<Listener<E>> li = listenerList.listIterator(listenerList.size());
    while (li.hasPrevious()) {
        li.previous().changed(event);
    }
}
Run Code Online (Sandbox Code Playgroud)

有一个可以修改和迭代的监听器列表。我认为前向迭代(参见方法#fireChangedForward)应该是安全的。 问题是:反向迭代(参见方法#fireChangedReversed)在多线程环境中也安全吗? 我对此表示怀疑,因为涉及两个调用:#size 和#listIterator。 如果它不是线程安全的,那么在以下情况下实现#fireChangedReversed的最有效方法是什么:

  • 优化遍历
  • 如果可能的话避免使用锁定
  • 避免使用 javax.swing.event.EventListenerList
  • 更喜欢不使用第三方库的解决方案,例如可以在自己的代码中实现

java collections

5
推荐指数
1
解决办法
541
查看次数