ThreadLocal源码,骚气的for循环 | Java Debug 笔记

235 阅读1分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看活动链接

一 ThreadLocal set方法分析

   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();
}

这里面有一个for循环,很骚气,for循环不是应该for(int i=0;i<list.size();i++)吗? 或者是foreach的写法吗?

for (Entry e = tab[i];
     e != null;
     e = tab[i = nextIndex(i, len)])
     

就是这段骚气的for循环,仔细看了一下,这段代码其实就是for循环的基础变种,意思就是如果e!=null时就会一直执行下去Entry e = tab[i]是初始值,相当与i =0,e = tab[i = nextIndex(i, len)] 是一个变化的值,相当于i++。

二 结语

源码的阅读不是一蹴而就的,而是需要不断的循序渐进,如果太过着急,就一定会适得其反。