Java ThreadLocal 类
来源:互联网 发布:网吧系统还原软件 编辑:程序博客网 时间:2024/05/08 00:38
一个例子(参考自张孝祥老师的视频)
代码
package com.jue.test_thread_local;import java.util.Random;public class TestMain {private static ThreadLocal<Integer> tl = new ThreadLocal<Integer>();public static void main(String[] args) {TestMain tm = new TestMain();tm.test();}public void test() {for (int i = 0; i < 3; i++) {new Thread() {@Overridepublic void run() {int data = new Random().nextInt(200);tl.set(data);System.out.println(Thread.currentThread().getName() + " thread data = " + data);new A().testA();}}.start();}}static class A {public void testA() {System.out.println("A -> testA() " + Thread.currentThread().getName() + " thread data " + tl.get());}}}结果
TestMain-> test Thread-1 thread data = 199TestMain-> test Thread-2 thread data = 16TestMain-> test Thread-0 thread data = 55A->testA() Thread-2 thread data 16A->testA() Thread-1 thread data 199A->testA() Thread-0 thread data 55
每个线程一个单例的实现
ThreadSingleton
public class ThreadSingleton {private String threadName;private static ThreadLocal<ThreadSingleton> sThreadLocal = new ThreadLocal<ThreadSingleton>();private ThreadSingleton(String name) {threadName = name;}public static ThreadSingleton getInstance() {if (sThreadLocal.get() == null) {String name = Thread.currentThread().getName();sThreadLocal.set(new ThreadSingleton(name));}return sThreadLocal.get();}@Overridepublic String toString() {return "ThreadSingleton, threadName = " + threadName + " #" + this.hashCode();}}注意:getInstance方法不需要加synchronized同步锁
TestMain
public class TestMain {public static void main(String args[]) {for (int i = 0; i < 5; i++) {new Thread() {@Overridepublic void run() {ThreadSingleton ts1 = ThreadSingleton.getInstance();ThreadSingleton ts2 = ThreadSingleton.getInstance();System.out.println(ts1);System.out.println(ts2);}}.start();}}}输出结果
ThreadSingleton, threadName = Thread-2 #1024915921ThreadSingleton, threadName = Thread-2 #1024915921ThreadSingleton, threadName = Thread-3 #2121724417ThreadSingleton, threadName = Thread-3 #2121724417ThreadSingleton, threadName = Thread-0 #1647036297ThreadSingleton, threadName = Thread-0 #1647036297ThreadSingleton, threadName = Thread-1 #113690433ThreadSingleton, threadName = Thread-4 #185211847ThreadSingleton, threadName = Thread-1 #113690433ThreadSingleton, threadName = Thread-4 #185211847
源码分析
字段
private final int threadLocalHashCode = nextHashCode();
记录当前hashCode值方法
返回下一个hashCode
/** * Returns the next hash code. */ private static int nextHashCode() { return nextHashCode.getAndAdd(HASH_INCREMENT); }返回当前线程存储的 thread-local variable
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(); }我们查看getMap(t)方法,发现访问的是Thread类的threadLocals字段
ThreadLocalMap getMap(Thread t) { return t.threadLocals; }查看Thread类发现下面的字段,即:thread-local variable 是因为thread对象的间接持有
ThreadLocal.ThreadLocalMap threadLocals = null;设置当前线程的thread -local variable
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }移除当前线程的thread-local variable
public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); }静态内部类ThreadLocalMap
静态内部类Entry
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
Entry继承自WeakReferenceEntry key为ThreadLocal<?>,value为ThreadLocal的T
当key为null的时候,表示key不再引用,代表实体可以从表中除去
Entry数组
private Entry[] table;构造器
关于ThreadLocalMap
- ThreadLocalMap是一个用户自定义的hash map。
- ThreadLocalMap适合掌管线程本地数据
- ThreadLocalMap没有暴露任何操作给ThreadLocal类之外的类
- ThreadLocalMap package内可见,为了允许Thread类的访问
- 为了处理大个,生命周期长的使用情况,hash表entry使用WeakReference做key
- 引用队列如果没有使用,entry只能保证在空间不足的时候remove掉
ThreadLocal 与 ThreadLocalMap 、Entry、Thread的关系
- 一个线程持有一个ThreadLocalMap引用
- 一个ThreadLocalMap可以持有多个Entry,ThreadLocalMap本身就持有Entry 数组的引用
- 一个Entry持有一个ThreadLocal的Weak Reference
- 间接的:一个线程可以持有多个ThreadLocal的引用
- 一个ThreadLocal引用可以被多个线程分别持有
0 0
- Java.lang.ThreadLocal类
- java的ThreadLocal类
- Java中的ThreadLocal类
- Java中的ThreadLocal类
- java.lang.ThreadLocal类
- java.lang.ThreadLocal类
- java.lang.ThreadLocal类
- java.lang.ThreadLocal类
- Java ThreadLocal类
- java.lang.ThreadLocal类
- java.lang.ThreadLocal类
- java多线程--ThreadLocal类
- Java ThreadLocal 类
- Java多线程-ThreadLocal类
- Java并发ThreadLocal类
- Java中的ThreadLocal类
- java.lang.ThreadLocal类
- 研究java.lang.ThreadLocal类
- iOS常见问题之 真机测试Could not find Developer Disk Image
- 字符串的添加/插入/移除
- 对.lds连接脚本文件的分析
- TestNG+Spring集成测试示例
- leetcode104: Maximum Depth of Binary Tree
- Java ThreadLocal 类
- GetModuleFileName函数的用法
- 一个内存报警问题总结
- Spring HTTP Invoker使用
- 【驱动开发】001 Hello world
- java之路
- Groovy学习笔记
- 学习笔记--我的第一个爬虫项目
- 第八周拓展实践(6)都要学C