前言
数据结构
线程缓存ThreadLocal
原来思路
private static final Map<Long,Object> ThreadLoacl1 = new HashMap<>();
static {
ThreadLoacl1.put(Thread.currentThread().getId(),"value");
}
正确思路
Thread{
ThreadLocalMap threadLocals
}
// 自己新建的一个Map,就是一个数组,只不过存取的时候下标按照hash来算出来的
ThreadLocalMap{
Entry[] table
}
Entry{
ThreadLocal tl;
Object value;
}
合并一块:
Thread{
[{ThreadLocal , Object },{ThreadLocal , Object }]
}
也就是数据是在Thread中存储着呢,而 static的ThreadLocal 才是哪个key。
Thread和ThreadLocal关系
两个在一个packge内
Thread.threadLocals 是 default,也就是包内类可见
ThreadLocal中可以给Thread对象的threadLocals属性直接赋值
Thread.inheritableThreadLocals类似threadLocals,只不过是给InheritableThreadLocal访问的
InheritableThreadLocal 是ThreadLocal子类
在new Thread()的时候,init方法 会将当前线程的inheritableThreadLocals属性中的值,赋值给子线程inheritableThreadLocals变量中
ThreadLocal
获取当前线程
Thread t = Thread.currentThread();
getMap 方法
ThreadLocal中:return t.threadLocals
InheritableThreadLocal重写了该方法:return t.inheritableThreadLocals;
set 设置值
获取Thread中的ThreadLocals Map对象,存储数据到Map中
MyThreadLocal1.ThreadLocalMap map = getMap((MyThread1) t);
if (map != null)
map.set(this, value);
get 获取值
获取Thread中的ThreadLocals Map对象,获取数据从Map中
// 获取线程Thread中map数据
MyThreadLocal1.ThreadLocalMap map = getMap(t);
if (map != null) {
// <当前ThreadLocal引用,引用>
MyThreadLocal1.ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
createInheritedMap
复制一个继承来的Map
ThreadLocalMap
expunge 清除
Stale 腐烂
slot 槽位,map中table数组的一个元素
Entry
Entry extends WeakReference<MyThreadLocal1<?>>
Entity中比如有属性是弱引用
这个弱引用是MyThreadLocal1类型
setThreshold
设置rehash阈值,即超过2/3就rehash
rehash
expungeStaleEntries 清除腐烂实体
清除后占用 如果超过阈值 3/4就 resize
resize
数组长度翻倍,重写根据key来hash存储
HashCode
核心代码:new AtomicInteger().getAndAdd(0x61c88647)
private final int threadLocalHashCode = nextHashCode();
private static AtomicInteger nextHashCode = new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
/**
* 线程安全获取一个hashCode
* @return
*/
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
Thread
Thread
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
Init
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
inheritThreadLocals == true
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals){
Thread parent = currentThread();
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
InheritableThreadLocal
按照ThreadLocal的流程:
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
map.set
map.get
map.remove
只有getMap方法获取到的Thread对象属性不同
inheritableThreadLocals 才会被复制
threadLocals是不会被复制的
InheritableThreadLocal:
ThreadLocalMap getMap(Thread var1) {
return var1.inheritableThreadLocals;
}
测试验证
out:
thread name:Thread-0
mythread 2 local : null
mythread 2 inlocal : 345
public class Test3 {
public static ThreadLocal tl = new ThreadLocal();
public static InheritableThreadLocal itl = new InheritableThreadLocal();
public static void main(String[] args) {
final Thread thread = Thread.currentThread();
tl.set("123");
itl.set("345");
new MyThread2().start();
try {
Thread.sleep(10 * 1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread2 extends Thread{
public MyThread2(){
super();
}
@Override
public void run() {
System.out.println("thread name:"+super.getName());
try {
Thread.sleep(1 * 1000l);
System.out.println("mythread 2 local : " + Test3.tl.get());
System.out.println("mythread 2 inlocal : " + Test3.itl.get());
Thread.sleep(3 * 1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ThreadLocal&InheritableThreadLocal&TransmittableThreadLocal
比较
ThreadLocal:
- 一个线程内
- 父子线程 不能传递值
InheritableThreadLocal
- extends ThreadLocal
- 父子线程,传递过程是new Thread
- 线程复用,线程池场景,就会发现线程是上次的
TransmittableThreadLocal,
- extends InheritableThreadLocal
- 可传递,在线程池借出线程和回收线程改造,所以线程池必须用代理的,否则不生效,就是父子线程传值
示例
out:
========== 0
pool-1-thread-1 local : null
pool-1-thread-1 inlocal : --- 0
pool-1-thread-1 transmittable : --- 0
========== 1
pool-1-thread-2 local : null
pool-1-thread-2 inlocal : --- 1
pool-1-thread-2 transmittable : --- 1
========== 2
pool-1-thread-2 local : null
pool-1-thread-2 inlocal : --- 1
pool-1-thread-2 transmittable : --- 2
import java.util.concurrent.*;
public class ThreadPoolTester {
private static ExecutorService pool;
public static ThreadLocal tl = new ThreadLocal();
public static InheritableThreadLocal itl = new InheritableThreadLocal();
public static TransmittableThreadLocal ttl = new TransmittableThreadLocal();
public static void main(String[] args) {
//maximumPoolSize设置为2 ,拒绝策略为AbortPolic策略,直接抛出异常
pool = TtlExecutors.getTtlExecutorService(new ThreadPoolExecutor(1,
2,
1000,
TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()));
for (int i = 0; i < 3; i++) {
tl.set(" --- " + i);
itl.set(" --- " + i);
ttl.set(" --- " + i);
System.out.println("========== " + i);
pool.execute(new ThreadTask());
try {
Thread.sleep(2 * 1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class ThreadTask implements Runnable {
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" local : " + ThreadPoolTester.tl.get());
System.out.println( Thread.currentThread().getName()+" inlocal : " + ThreadPoolTester.itl.get());
System.out.println(Thread.currentThread().getName()+" transmittable : " + ThreadPoolTester.ttl.get()+"\n");
Thread.sleep(2 * 1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
附录
无