ThreadLocal
来源:互联网 发布:美国gdp数据公布网站 编辑:程序博客网 时间:2024/06/13 02:51
1.主要作用
每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子可以存储每个线程的私有数据
ThreadLocal类提供的几个方法
⑴public T get() { }⑵public void set(T value) { }⑶public void remove() { }⑷protected T initialValue() { } initialValue()是一个protected方法,一般是用来在使用时进行重写的,否则需要先set再get内部原理:
ThreadLocal类中有一个静态内部类ThreadLocalMap(其类似于Map),用键值对的形式存储每一个线程的变量副本,
ThreadLocalMap中元素的key为当前ThreadLocal对象,而value对应线程的变量副本,每个线程可能存在多个ThreadLocal。
2.ThreadLocal使用
因为在上面的代码分析过程中,我们发现如果没有先set的话,即在map中查找不到对应的存储,则会通过调用setInitialValue方法返回i,
而在setInitialValue方法中,有一个语句是T value = initialValue(), 而默认情况下,initialValue方法返回的是null。
⑴例子1
public class MyThreadLocal { //定义了一个ThreadLocal变量,用来保存int或Integer数据 private ThreadLocal<Integer> tl = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return 0; } }; public Integer getNextNum() { //将tl的值获取后加1,并更新设置t1的值 tl.set(tl.get() + 1); return tl.get(); } }
public class TestThread extends Thread { private MyThreadLocal tlt = new MyThreadLocal(); public TestThread(MyThreadLocal tlt) { this.tlt = tlt; } @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + "\t" + tlt.getNextNum()); } } }
public class Test { public static void main(String[] args) { MyThreadLocal tlt = new MyThreadLocal(); Thread t1 = new TestThread(tlt); Thread t2 = new TestThread(tlt); Thread t3 = new TestThread(tlt); Thread t4 = new TestThread(tlt); t1.start(); t2.start(); t3.start(); t4.start(); } }输出:四个线程互相不影响
Thread-0 1 Thread-1 1 Thread-0 2 Thread-1 2 Thread-0 3 Thread-1 3 Thread-2 1 Thread-3 1 Thread-2 2 Thread-3 2 Thread-2 3 Thread-3 33.InheritableThreadLocal 使用
用InheritableThreadLocal可以让子线程从父线程取得值,也可以进行更改,但是需要注意:当子线程取得值的同时,主线程将
InheritableThreadLocal中的值进行更改,那么子线程取到的值还是旧值。
package Thread14;public class ThreadA extends Thread {@Override public void run() { try { for (int i = 0; i < 10; i++) { System.out.println("在ThreadA线程中取值=" + Tools.tl.get()); Thread.sleep(100); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package Thread14;import java.util.Date;public class InheritableThreadLocalExt extends InheritableThreadLocal { @Override protected Object initialValue() { return new Date().getTime(); } @Override protected Object childValue(Object parentValue) { return parentValue + " 我在子线程加的~!"; } }
package Thread14;public class Tools { public static InheritableThreadLocalExt tl = new InheritableThreadLocalExt(); }
package Thread14;public class Run { public static void main(String[] args) { try { for (int i = 0; i < 10; i++) { System.out.println(" 在Main线程中取值=" + Tools.tl.get()); Thread.sleep(100); } Thread.sleep(5000); ThreadA a = new ThreadA(); a.start(); } catch (InterruptedException e) { e.printStackTrace(); } } }输出:
在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745 在Main线程中取值=1507176008745在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!在ThreadA线程中取值=1507176008745 我在子线程加的~!
0 0
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- threadlocal
- ThreadLocal
- ThreadLocal
- leetcode--Maximum Depth of Binary Tree
- linux基本命令
- 双重权值(SPFA算法)
- cudnn环境变量配置
- XSS和CSRF区别?
- ThreadLocal
- linux之scp
- HDU 1232 畅通工程(并查集)
- 内置服务$http,登录案例
- Actor
- Angular之路由篇一
- leetcode--Best Time to Buy and Sell Stock
- Canvas与SVG
- 剑指Offer——(3)从尾到头打印链表