大家都在说的
HashMap
并发问题居然真碰上了🤣.
1
mortonnex 2018-11-09 13:22:45 +08:00 via iPhone
点赞
|
2
YAHIKO0 2018-11-09 13:28:04 +08:00
d=====( ̄▽ ̄*)b
|
3
crossoverJie OP |
4
jy02201949 2018-11-09 13:35:04 +08:00
@crossoverJie #3 智能送分机器人
|
5
YAHIKO0 2018-11-09 13:35:38 +08:00
点赞,
@crossoverJie |
6
coolcfan 2018-11-09 13:55:25 +08:00 via Android
可以直接 Collections.newSetFromMap(new ConcurrentHashMap ()),无缝替换掉,省掉手动写死 value
|
7
crossoverJie OP |
8
aimaodeyuer 2018-11-09 14:17:20 +08:00
追踪问题的能力还是要向大佬学习!
|
9
amon 2018-11-09 14:35:31 +08:00
点赞,这个问题只是理论上听到过,还真没看到过,哈哈。
|
10
Jokerrrrrr 2018-11-09 14:41:24 +08:00
分析排查的,有点厉害
|
11
Antidictator 2018-11-09 14:50:47 +08:00
点赞+1
|
12
TommyLemon 2018-11-09 15:01:39 +08:00
赞。
我第一次看到 HashSet 的实现源码也震惊了,居然是用 HashMap 实现的, HashSet 里的所有 value 存到了 HashMap 里的所有 key,HashMap 的 value 则是全局的 private static final Object PRESENT = new Object(); 文中用 ConcurrentHashMap 替代 HashSet 并写死 value 的做法, 其实就是把 HashSet 简单地重新实现了一遍,并保证线程安全。 |
13
TommyLemon 2018-11-09 15:07:10 +08:00
@TommyLemon 至于形成环形链表的原因我看到问题就猜出来是
多线程并发执行 set.add(key) 时同一个 key 被添加多次,然后导致 valueI = key valueJ = key 当循环里通过 value = value.next 形成了从 valueI 到 valueJ 的环形链表 |
14
BBCCBB 2018-11-09 15:07:29 +08:00
这..... 这难道不是常识吗?
Collections.newSetFromMap(new ConcurrentHashMap<>()) |
15
crossoverJie OP |
16
crossoverJie OP @BBCCBB #14
我确实是很少用 Collections.newSetFromMap 这个 API,有并发 set 要求都是用自己封装的 ConcurrentHashMap,不过原理都是一样的,不用过多纠结。 |
17
x66 2018-11-09 16:42:45 +08:00
感觉 Set 是为了去重,感觉 Redis 更适合干这事。
|
18
crossoverJie OP |