JAVA多线程-线程间通信(五)-类ThreadLocal的使用
来源:互联网 发布:elasticsearch5 linux 编辑:程序博客网 时间:2024/05/21 15:43
类ThreadLocal的使用
变量值的共享可以使用public static的形式,所有的线程都是用同一个public static变量。如果想实现每一个线程都有自己的共享变量该如何解决呢?
类ThreadLocal主要解决的是:每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储每一个线程的私有数据。
1、方法get()与null
package org.jksoft.thread.threadLocal;/** * 测试一:ThreadLocal的get()方法与null * @author mcl * * 2016-2-21-上午10:09:36 */public class Test1 {public static ThreadLocal t = new ThreadLocal();public static void main(String[] args) {if(t.get()==null){System.out.println("从未存放过值......");t.set("我存放的值");}System.out.println(t.get());System.out.println(t.get());}}运行结果:
结论:
从上面的结果中来看,第一次调用t对象的get()方法,返回值为null,通过调用set()方法赋值后,顺利取出值并打印到控制台上。类ThreadLocal解决的是变量在不同线程间的隔离性,也就是不同线程用你有自己的值,不同线程中的值,是可以放到ThreadLocal类中进行保存的。
2、验证线程变量的隔离型
package org.jksoft.thread.threadLocal;/** * 测试二:验证线程变量的隔离性 * * @author mcl * * 2016-2-21-上午10:09:36 */public class Test2 {//主线程:启动线程A和线程B,自己从ThreadLocal中取值public static void main(String[] args) {new ThreadA().start();new ThreadB().start();for (int i = 0; i < 100; i++) {try {Tools.t.set("Main SET: " + (i + 1));System.out.println("Main GET: " + Tools.t.get());Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class ThreadA extends Thread {public void run() {for (int i = 0; i < 100; i++) {try {Tools.t.set("ThreadA SET: " + (i + 1));System.out.println("ThreadA GET: " + Tools.t.get());Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class ThreadB extends Thread {public void run() {for (int i = 0; i < 100; i++) {try {Tools.t.set("ThreadB SET: " + (i + 1));System.out.println("ThreadB GET: " + Tools.t.get());Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class Tools {public static ThreadLocal t = new ThreadLocal();}结果:
结果分析:
我们可以看到,虽然三个线程都在t对象中set()数据值,但每个线程还是能取出自己的数据。
3、我们如何解决,让ThreadLocal的对象中存在默认值,而不是null呢?
package org.jksoft.thread.threadLocal;/** * 测试三,为ThreadLocal的对象添加默认值,而不是null * * @author mcl * * 2016-2-21-上午10:09:36 */public class Test3 {public static MyThreadLocal t = new MyThreadLocal();public static void main(String[] args) {if(t.get()==null){System.out.println("我没有被初始化");t.set("测试一下");}System.out.println(t.get());System.out.println(t.get());}}class MyThreadLocal extends ThreadLocal{@Overrideprotected Object initialValue() {// TODO Auto-generated method stubreturn "我已经被初始化了,不再为null值";}}结果展示:
4、类InheritableThreadLocal的使用
使用类InheritableThreadLocal可以在子线程中取得父线程继承下来的值。
测试案例:
package org.jksoft.thread.threadLocal;import java.util.Date;/** * 测试四、InheritableThreadLocal的使用 * * @author mcl * * 2016-2-21-上午10:09:36 */public class Test4 {public static void main(String[] args) {for(int i=0;i<10;i++){System.out.println("Main :"+Tool.t.get());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}new ThreadC().start();}}class ThreadC extends Thread{public void run(){for(int i=0;i<10;i++){System.out.println("ThreadC :"+Tool.t.get());try {sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class InheritableThreadLocalExt extends InheritableThreadLocal{@Overrideprotected Object initialValue() {// TODO Auto-generated method stubreturn new Date().getTime();}@Overrideprotected Object childValue(Object parentValue) {// TODO Auto-generated method stubreturn parentValue+"我在子线程添加的";}}class Tool{public static InheritableThreadLocalExt t = new InheritableThreadLocalExt();}
测试结果:
注意:如果子线程在取得值的同时,主线程将InheritableThreadLocal中的值进行更改,那么子线程取到的值还是旧值。
修改Test4中的main方法如下,我们再来查看一下运行结果:
public static void main(String[] args) {for(int i=0;i<10;i++){System.out.println("Main :"+Tool.t.get());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}new ThreadC().start();Tool.t.set(new Date().getTime());for(int i=0;i<10;i++){System.out.println("Main :"+Tool.t.get());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}结果如下:截取部分结果
- JAVA多线程-线程间通信(五)-类ThreadLocal的使用
- Java多线程编程3--线程间通信--类ThreadLocal与类InheritableThreadLocal的使用
- Java多线程之通过管道线程间通信(字节流、字符流),类ThreadLocal与类InheritableThreadLocal的使用
- ThreadLocal多线程通信的使用
- java多线程学习五:线程间的通信
- JAVA多线程-线程间通信(四)-join的使用
- Java多线程技术研究(二)-线程同步,通信及ThreadLocal
- Java的多线程-线程间的通信
- 【Java多线程】线程间的通信
- Java多线程-线程间的通信
- Java多线程--线程间通信
- Java多线程编程-(3)-线程本地ThreadLocal的介绍与使用
- Java多线程编程-(4)-线程本地ThreadLocal的介绍与使用
- Java多线程编程-(3)-线程本地ThreadLocal的介绍与使用
- java线程中ThreadLocal类的使用及介绍
- (三) Java多线程详解之线程范围内共享变量及ThreadLocal类使用
- JAVA多线程---Condition使用---线程通信
- Java基础:多线程之线程范围内的数据共享ThreadLocal
- HDOJ 5631Rikka with Graph(图论)
- 机房重构—组合查询&模板方法
- ubuntu安装navicat及常见问题解决
- 544 - Heavy Cargo
- POJ 1014 Dividing
- JAVA多线程-线程间通信(五)-类ThreadLocal的使用
- 《计算机网络》知识要点一
- 4278: [ONTAK2015]Tasowanie 后缀数组+贪心
- spring拦截器配置
- Servlet—HttpServletResponse
- CodeForces 630 G. Challenge Pennants(组合数学)
- 《JAVA语言程序设计》(二)
- exec , xargs
- 2015年Android开发新技术小结