|
1
赞一下,Github 的文档整理的很有用,面试帮了不少忙
|
|
2
@AntiGameZ #1
|
|
guoyuchuanJul 23, 2018
3
正在看 GitHub 里面的东西,得用只是来充实自己。
|
|
guoyuchuanJul 23, 2018
4
你的博客加载好慢啊,得等一会才能进去
|
|
nVoxelJul 23, 2018
5
主题是不是换过?印象还挺深的~
|
|
6
@nVoxel #5 主题没换 就是换了一个配置 不想折腾博客了 但总得有点新鲜感
|
|
7
@guoyuchuan #4 没办法 用的 cloudflare 的 DNS 很慢,迁移到国内又要备案
|
|
lsmgeb89Jul 23, 2018
8
只记得完全无锁的实现非常复杂
|
|
amonJul 23, 2018
9
哎?每当关注了一个公众号不久,就在 v 站也看到作者。
幸会幸会! |
|
10
@amon #9 哈哈 V 站的人都超有趣的 很喜欢这里。
|
|
LostMoonkinJul 23, 2018
11
看着博客的背景总感觉我屏幕脏了 /doge
|
|
burenshiwoJul 23, 2018
12
阿里的学渣.....
|
|
13
@chenjian026 #12 那篇还有人记着呢
|
|
ormJul 23, 2018
14
博客访问很慢
|
|
alamayaJul 23, 2018
15
当时看的时候觉得最复杂的是扩容那一块,你这篇好象没有涉及
|
|
16
@alamaya #15 嗯 扩容那块很复杂,得单独拿一篇讲才行。
|
|
17
@orm #14 看来迁回国内得提上议程了。
|
|
llxx510200Jul 23, 2018
18
要是问我红黑树可咋整啊
|
|
19
@llxx510200 #18 这个我觉得能讲清楚为啥快,啥时候翻转这些就差不多了。具体实现确实很复杂
|
|
yuan93Jul 23, 2018
20
楼主博客可以转载到 oschina 吗?会备注原地址
|
|
beny2morJul 23, 2018
21
mark 一下
|
|
22
@liuzhen #20 可以的。
|
|
AntidictatorJul 23, 2018 via iPhone
23
支持一下
|
|
LuckCodeJul 23, 2018 via iPhone
24
我去,从博客看到公众号,今天在 v 站看到了作者。
缘分啊,py 交易一下。 |
|
25
支持。最近用 pandoc 把你的 repo 转换成了 epub 在手机上看,受益良多
|
|
26
@LuckCode #24 哈哈 我这是广撒网啊 你也是哪个网都钻进来了
|
|
27
|
|
zxq1002Jul 23, 2018 via Android
28
打开好慢。。
|
|
WildCatJul 23, 2018
29
@crossoverJie 我目前转换的有问题,不过我先开个 issue 抛砖引玉吧
|
|
30
@zxq1002 #28 确实挺慢的,准备转到国内了。
|
|
shidapiJul 24, 2018
31
打不开。。。
|
|
32
@shiguiyou #31 多等等 卡。。
|
|
mrrobot97Jul 24, 2018
33
safari 禁用了 Flash 打开网页后风扇开始怒吼..
|
|
zpxshlJul 24, 2018 via Android
34
我来提(请教)个问题。
1.8 版 concurrentHM,当使用 cas 插入,如何保证结果对其他线程可见。 volatile 不保证数组元素的可见性。 |
|
35
|
|
zpxshlJul 25, 2018 via Android
36
|
|
37
@zpxshl #36 嗯 你不是问的怎么保证可见性嘛,获取到的是最新值就不会有可见性的问题了。
|
|
zpxshlJul 25, 2018 via Android
38
@crossoverJie 可见性...... 是一个变量修改其他线程都可以见到。 你获取到最新值,(为空时) cas 插入。 此时数组元素被修改,如何保证其他线程见到你的修改?
|
|
39
|
|
zpxshlJul 25, 2018 via Android
40
@crossoverJie 朋友。getObjectVolatile 只是获得主内存的数据。并没有强制将其他线程的工作内存数据刷新回主内存的功能。 也就是说 当你 cas 修改数组数据后,如果没有将数据缓存刷回主内存。其他线程用 getObjectVolatile 也读不到最新的值。
|
|
41
@zpxshl #40 兄弟,我觉得这没有啥问题呀。
用 CAS 的前提是,遍历数组的时候在 key 所映射的那个位置是空的,也就是没有其他线程使用的时候才会在 2 处利用 CAS 尝试写入一个 Node。 也就是说写入成功的话是不会有线程竞争的,这样也就不会存在你说的可见性问题(如果这时有线程来做 get ,恰好也定位到这个位置,那在写入线程更新成功之前获取的肯定也是空)。 如果写入失败,CAS 返回 false,这样就会重新从 1 处再次循环。 这样如果当前位置有数据了那就会用 synchronized 来写,用 synchronized 的话也不会出现可见性问题。 如果当前位置依然为空的话就会重复上面的步骤。 |
|
zpxshlJul 26, 2018 via Android
42
@crossoverJie
a 线程,遍历数组的时候在 key 所映射的那个位置是空的,cas 插入成功。 b 线程,同样找到那个位置发现同样为空( cas 插入的数值对 b 线程不一定可见的),又 cas 插入,那不就出问题啦? |
|
43
@zpxshl #42
如果 A 线程写入成功之后 B 线程就算是恰巧在 A 线程还未写入之前判断到是空进入了 CAS 的逻辑。 由于最终调用的还是 casTabAt() 底层调用的是 unsafe.compareAndSwapObject 方法,他的期望是当前值为 null ,才会写入一个新的 Node。 由于该方法是线程安全的,此时当前值已经不为 null 了,所以必定会写入失败。 还有一个是,虽然是用 volatile 修饰的数组,但是用的是 getObjectVolatile 和 putObjectVolatile,依然可以保证可见性。 见: https://stackoverflow.com/questions/31534706/about-unsafe-getobjectvolatile-usage |
|
zpxshlJul 27, 2018
44
@crossoverJie 感谢!
|
|
c4f36e5766583218Mar 30, 2019
45
jdk7 先扩容再 put 值;
``` void addEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); } createEntry(hash, key, value, bucketIndex); } ``` jdk8 先 put 值再扩容: ```java.util.HashMap#putVal(int, K, V, boolean, boolean)``` 为什么?这么改动?有什么区别吗? |