ThreadLocal学习笔记
Posted 等待戈多儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreadLocal学习笔记相关的知识,希望对你有一定的参考价值。
可参考《实战Java高并发程序设计》4.3
ThreadLocal是一个线程的局部变量,只有当前线程可以访问的数据。所以是线程安全的。
为每一个线程分配不同的对象,需要在应用层面保证。ThreadLocal只是起到了简单容器的作用。如果在应用上为每一个线程分配了相同的对象,ThreadLocal也不能保证线程安全。
/**
*ThreadLocal简单使用
*/
public class TestTheadLocal
static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
public static class ParseDate implements Runnable
int i = 0;
public ParseDate(int i)
this.i = i;
@Override
public void run()
if (tl.get() == null)
tl.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
try
Date t = tl.get().parse("2016-06-29" + i % 60);
System.out.println(i + ":" + t);
catch (ParseException e)
e.printStackTrace();
使用ThreadLocal为每一个线程都产生一个SimpleDateFormt对象实例。
实现原理(Jdk1.8的源码):其内部数据结构可以理解为一个HashMap,用户存储线程引用
set
public void set(T value)
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
get
public T get()
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
return setInitialValue();
/**
* Remove the entry for key.
*/
private void remove(ThreadLocal<?> key)
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)])
if (e.get() == key)
e.clear();
expungeStaleEntry(i);
return;
如果对象对于竞争的处理容易引起性能损失,应考虑使用ThreadLocal为每个线程分配单独的对象。典型案例就是多线程环境下产生随机数。
以上是关于ThreadLocal学习笔记的主要内容,如果未能解决你的问题,请参考以下文章