一 前言
千呼万唤始出来,犹抱琵琶半遮面
在代码的世界里,陌生永远都应该是这条路上最熟悉的词,因为只有陌上才能拓宽,只有陌生,才更有挑战。
好的,不白话了,说说ThreadLocal中遇到的好东西,我们常说的 ++i登场了。
之前我有写过i++和++i通过字节码的解释,但是并没有在程序中看到++i的使用场景,结果今天遇到了。
二 代码
private void set(ThreadLocal key, Object value) {
// We don't use a fast path as with get() because it is at
// least as common to use set() to create new entries as
// it is to replace existing ones, in which case, a fast
// path would fail more often than not.
Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1);
for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal k = e.get();
if (k == key) {
e.value = value;
return;
}
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
还是这个set方法 int sz = ++size; 看到后我挺惊讶的,因为工作了几年就没见过++i的使用,然后回想下,i++ 与 ++i
居然迷惘了,i++ 是从局部变量表中取数据放入栈,然后对局部变量表+1,然后读取栈的数据,那栈的数据不变,如果这样的话,下面的代码岂不是最终输出都是0;
int i = 0;
for(int j =0;j<10;j++){
System.out.println(i++);
}
然后输出打印 是 0 1 2······ 和我想的不一样,最终想到了为什么,因为虽然读取了栈的值,但是对局部变量表的+1 也不是白家的。上面的局部变量还是加了1。
然后我们说说为什么使用++size,使用++i 其实还有一个好处就是性能,如果通过查看字节码来解释就是 ++i是在栈中对数据+1 而不是在局部变量表+1 所以更快一些。