静态ConcurrentHashmap是否需要外部同步

发布于 2024-11-19 03:47:52 字数 44 浏览 3 评论 0原文

静态ConcurrentHashmap是否需要使用同步块或锁进行外部同步?

Does the static ConcurrentHashmap need to be externaly synchronized using synchronize block or locks?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

走走停停 2024-11-26 03:47:52

是和不是。这取决于你在做什么。 ConcurrentHashMap 对于它的所有方法(例如 get 和 put)都是线程安全的。但是,对于非原子操作来说,它不是线程安全的。下面是一个执行非原子操作的方法示例:

public class Foo {
    Map<String, Object> map = new ConcurrentHashMap<String, Object>();

    public Object getFoo(String bar) {
        Object value = foo.get(bar);
        if (value == null) {
            value = new Object();
            map.put(bar, foo);
        }
        return value;
    }
}

这里的缺陷是调用 getFoo 的两个线程可能会接收到不同的对象。请记住,在处理任何数据结构或类型时,即使像 int 这样简单,非原子操作始终需要外部同步。 AtomicInteger 和 ConcurrentHashMap 等类有助于使一些常见操作线程安全,但不能防止检查然后设置操作,例如上面的 getFoo 中的操作。

Yes and no. It depends on what you're doing. ConcurrentHashMap is thread safe for all of its methods (e.g. get and put). However, it is not thread safe for non-atomic operations. Here is an example a method that performs a non-atomic operation:

public class Foo {
    Map<String, Object> map = new ConcurrentHashMap<String, Object>();

    public Object getFoo(String bar) {
        Object value = foo.get(bar);
        if (value == null) {
            value = new Object();
            map.put(bar, foo);
        }
        return value;
    }
}

The flaw here is that it is possible for two threads calling getFoo to receive a different Object. Remember that when dealing with a any data structure or type, even as simple as an int, non-atomic operations always require external synchronization. Classes such as AtomicInteger and ConcurrentHashMap assist in making some common operations thread safe, but do not protect against check-then-set operations such as in getFoo above.

诗笺 2024-11-26 03:47:52

仅当需要获取集合上的锁时才需要外部同步。该集合不会暴露其内部锁。

ConcurrentMap 有 putIfAbsent,但是如果对象的创建成本很高,您可能不想使用它。

 final ConcurrentMap<Key, Value> map =

 public Value get(Key key) {
     // allow concurrent read
     return map.get(key);
 }

 public Value getOrCreate(Key key) {
     // could put an extra check here to avoid synchronization.
     synchronized(map) {
        Value val = map.get(key);
        if (val == null)
           map.put(key, val = new ExpensiveValue(key));
        return val;
     }
 }

You only need external synchronization if you need to obtain a lock on the collection. The collection doesn't expose its internal locks.

ConcurrentMap has putIfAbsent, however if the creation of the object is expensive you may not want to use this.

 final ConcurrentMap<Key, Value> map =

 public Value get(Key key) {
     // allow concurrent read
     return map.get(key);
 }

 public Value getOrCreate(Key key) {
     // could put an extra check here to avoid synchronization.
     synchronized(map) {
        Value val = map.get(key);
        if (val == null)
           map.put(key, val = new ExpensiveValue(key));
        return val;
     }
 }
强辩 2024-11-26 03:47:52

据我所知,所有需要的锁定都是在此类中完成的,因此您无需太担心,以防万一您没有做一些特定的事情并且需要它像那样发挥作用。

http://download.oracle。 com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html 它说:

但是,即使所有操作都是线程安全的,检索操作也不需要锁定,并且不支持以阻止所有访问的方式锁定整个表。

检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠。检索反映了最近完成的更新操作在其开始时的结果。

因此,如果这在您的特定应用程序中不代表任何问题,您无需担心。

As far as I know all needed locking is done in this class so that you don't need to worry about it too much in case you are not doing some specific things and need it to function like that.

On http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html it says:

However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access.

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset.

So in case this does not represent any problems in your specific application you do not need to worry about it.

謌踐踏愛綪 2024-11-26 03:47:52

否:不需要外部同步。

java.util.concurrent 类上的所有方法都是线程安全的。

No: No need to synchronise externally.

All methods on the java.util.concurrent classes are threadsafe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文