理解FastThreadLocal

今天看Netty源码,遇到如下一个东东:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

private static final FastThreadLocal<CodecOutputLists> CODEC_OUTPUT_LISTS_POOL =
        new FastThreadLocal<CodecOutputLists>() {
            @Override
            protected CodecOutputLists initialValue() throws Exception {
                // 16 CodecOutputList per Thread are cached.
                return new CodecOutputLists(16);
            }
        };

这使我产生了对FastThreadLocal的兴趣。简单的看了一下FastThreadLocal的JavaDoc文档,说明如下:

  • FastThreadLocal使用数组中的常量索引来查找变量,而不是使用哈希码和哈希表。虽然看起来很微妙,但与使用哈希表相比,它产生了轻微的性能优势,并且在频繁访问时很有用。

  • 要利用此线程局部变量,您的线程必须是FastThreadLocalThread或其子类型。 由于这个原因,默认情况下DefaultThreadFactory创建的所有线程都是FastThreadLocalThread。

  • 请注意,快速路径仅适用于扩展FastThreadLocalThread的线程,因为它需要一个特殊的字段来存储必要的状态。任何其他类型的线程的访问都会回退到常规的ThreadLocal。

得,又引入了一个新的知识点:FastThreadLocalThread。

对其进行的思考

我暂时对FastThreadLocal底层的东西并不感冒,这个东西真正吸引我的注意的地方是和我平时使用ThreadLocal的方法完全不同,我之前的写法如下:

1
2
3
4

ThreadLocal<User> cache2 = new ThreadLocal<>();
cache2.set(new User());

我因此去验证了一些ThreadLocal是否支持如上写法,结果发现真的支持:

1
2
3
4
5
6
7
8

ThreadLocal<User> cache = new ThreadLocal<User>() {
    @Override
    protected User initialValue() {
        return new User();
    }
};

果真活到老学到老,另外还有另一种写法,非常的优雅帅气:

1
2
3

ThreadLocal<User> cache = ThreadLocal.withInitial(User::new);