gpt4 book ai didi

java - 是否保证 ConcurrentHashMap.get() 可以通过不同的线程看到以前的 ConcurrentHashMap.put() ?

转载 作者:IT老高 更新时间:2023-10-28 20:53:01 25 4
gpt4 key购买 nike

ConcurrentHashMap.get() 保证看到以前的ConcurrentHashMap.put()通过不同的线程?我的期望是,阅读 JavaDocs 似乎表明了这一点,但我 99% 确信现实是不同的。在我的生产服务器上,似乎正在发生。 (我已经通过日志记录了它。)

伪代码示例:

static final ConcurrentHashMap map = new ConcurrentHashMap();
//sharedLock is key specific. One map, many keys. There is a 1:1
// relationship between key and Foo instance.
void doSomething(Semaphore sharedLock) {
boolean haveLock = sharedLock.tryAcquire(3000, MILLISECONDS);

if (haveLock) {
log("Have lock: " + threadId);
Foo foo = map.get("key");
log("foo=" + foo);

if (foo == null) {
log("New foo time! " + threadId);
foo = new Foo(); //foo is expensive to instance
map.put("key", foo);

} else
log("Found foo:" + threadId);

log("foo=" + foo);
sharedLock.release();

} else
log("No lock acquired");
}

似乎正在发生的事情是这样的:

Thread 1                          Thread 2
- request lock - request lock
- have lock - blocked waiting for lock
- get from map, nothing there
- create new foo
- place new foo in map
- logs foo.toString()
- release lock
- exit method - have lock
- get from map, NOTHING THERE!!! (Why not?)
- create new foo
- place new foo in map
- logs foo.toString()
- release lock
- exit method

所以,我的输出如下所示:

Have lock: 1    
foo=null
New foo time! 1
foo=foo@cafebabe420
Have lock: 2
foo=null
New foo time! 2
foo=foo@boof00boo

第二个线程不会立即看到 put!为什么?在我的生产系统上,有更多线程,我只看到一个线程,即紧随线程 1 的第一个线程有问题。

我什至尝试将 ConcurrentHashMap 上的并发级别缩小到 1,但这并不重要。例如:

static ConcurrentHashMap map = new ConcurrentHashMap(32, 1);

我哪里错了?我的期望?或者我的代码(真正的软件,不是上面的)中是否有一些错误导致了这种情况?我已经反复检查了它,并且 99% 确定我正确处理了锁定。我什至无法理解 ConcurrentHashMap 或 JVM 中的错误。 请救救我。

可能相关的 Gorey 细节:

  • 四核 64 位至强 (DL380 G5)
  • RHEL4(Linux mysvr 2.6.9-78.0.5.ELsmp #1 SMP ... x86_64 GNU/Linux)
  • Java 6(build 1.6.0_07-b0664-Bit Server VM(build 10.0-b23,混合模式))

最佳答案

这里有一些很好的答案,但据我所知,实际上没有人对所提出的问题提供规范的答案:“ConcurrentHashMap.get() 是否保证通过不同的线程看到以前的 ConcurrentHashMap.put()” .那些说是的人没有提供消息来源。

所以:是的,这是有保证的。 Source (参见“内存一致性属性”部分):

Actions in a thread prior to placing an object into any concurrent collection happen-before actions subsequent to the access or removal of that element from the collection in another thread.

关于java - 是否保证 ConcurrentHashMap.get() 可以通过不同的线程看到以前的 ConcurrentHashMap.put() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1770166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com