一个hashmap,多个线程访问
一个读线程调用hashMap.get("xx")
一个写线程重新赋值 hashMap = new HashMap()
会不会出现问题?
比如读的过程刚拿到key哈希之后的值,这个时候另一个线程重新assign了一个新的hashmap,这个理论上是会出问题的吧?
写了几个测试,都pass了,但是感觉不靠谱啊。
求指点。谢谢。
1
Valyrian 2015-08-04 03:04:19 +08:00 via iPhone
ConcurrentHashMap
|
2
final0pro OP @Valyrian 对,这个肯定可以。
但是我是想确定下,这种情况用hashmap会不会出现问题,出现什么样的问题? 一般hashmap并发出现死循环,是因为二个线程同时在rehash同一个hashmap 但是我的这种情况,一个只是get,永远不会rehash整个hashmap,所以应该不会出现死循环吧 |
5
Andiry 2015-08-04 05:01:11 +08:00
我不认为有啥问题,因为hashmap的reassign是原子的
除非hashmap.get()当中又使用了hashmap本身 |
6
final0pro OP @Andiry google了一下,assignment好像不是原子的
http://coolshell.cn/articles/265.html ``` 主要在于singleton = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。 给 singleton 分配内存 调用 Singleton 的构造函数来初始化成员变量,形成实例 将singleton对象指向分配的内存空间(执行完这步 singleton才是非 null 了) ``` 那这样,岂不是有可能会NullPointerException。。。null.get("xx")了。。。 |
7
Andiry 2015-08-04 05:35:50 +08:00
@final0pro 只要这三步按照顺序来就没问题,因为第三步是原子的,get线程永远不会看到NULL
当然像那篇文章里说的重排序就挂了 |
8
final0pro OP @Andiry 除了这种情况,会不会还有另外一种可能?:
thread1: get --》 拿到hash(key)的值 -》 线程被挂起 thread2: reassign了新的hashmap thread1:被唤醒,因为之前已经拿到hash(key)了,所以继续拿这个去array中找,但是key这个时候可能已经全被打乱了 感觉是有这个可能的,但是要在极度高并发的情况才有可能? |
9
Andiry 2015-08-04 05:59:44 +08:00 1
@final0pro 不会。即使thread2 reassign了hashmap,get访问的hashmap仍然是旧的那一个。除非旧hashmap在这个get过程当中被GC了。
|
10
qiyi 2015-08-04 06:51:02 +08:00 via iPhone 1
hashMap要么是旧的Map要么是新的Map ,没啥问题,copyonwritehashmap就这么实现
|
12
SoloCompany 2015-08-04 08:45:12 +08:00 via iPhone
加 violite 关键字
|
13
laipogo 2015-08-04 09:04:52 +08:00
@SoloCompany
volatile |
14
mind3x 2015-08-04 09:47:52 +08:00 via Android 2
@Andiry @qiyi 知道为什么 double checked locking 是错的吗?这里也是一样有 memory reordering 的问题,除非显式插入 barrier 保证顺序。
@final0pro 建议阅读老文 http://www.javaworld.com/article/2074979/java-concurrency/double-checked-locking--clever--but-broken.html |
15
final0pro OP @mind3x 学习了
但是这篇文章是2001年,java1.5诞生之前 根据http://coolshell.cn/articles/265.html这篇, ``` 但是,这个事情仅在Java 1.5版后有用,1.5版之前用这个变量也有问题,因为老版本的Java的内存模型是有缺陷的。 ``` 现在应该没问题了 |
17
qiyi 2015-08-05 02:19:25 +08:00 via iPhone
手机打字,纠正上面单词错误 ,volatile
|
18
Karlllll 2016-08-09 23:28:25 +08:00
题主,你的问题好像。。。。。
get 访问跟你重新把一个指针指向一个新的 hashMap ,没有关系。 |