ThreadLocal的使用

ThreadLocal的作用

从上一篇对于ThreadLocal的源码分析,可以看出ThreadLocal不是用来将解决共享对象的多线程访问问题,每个线程可以将线程的私有数据通过ThreadLocal的set方法设置到线程的私有的ThreadLocalMap中,其他线程无法访问到。各个线程中的ThreadLocal.ThreadLocalMap以及ThreadLocal.ThreadLocalMap中的数值都是不同对象

ThreadLocal的使用

首先定义一个全局共享的ThreadLocal

package com.ftf.thread.test;

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadLocalPool {
	public static final ThreadLocal<String> tl = new ThreadLocal<>();
	public static void main(String[] args) {
		LocalThread t1 = new LocalThread("线程A");
		LocalThread t2 = new LocalThread("线程B");
		LocalThread t3 = new LocalThread("线程C");
		LocalThread t4 = new LocalThread("线程D");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}
class LocalThread extends Thread{
	private static AtomicInteger at = new AtomicInteger();
	public LocalThread(String name){
		super(name);
	}
	@Override
	public void run() {
		for(int i = 0;i<3;i++){
			ThreadLocalPool.tl.set(at.incrementAndGet()+"");
			System.out.println(Thread.currentThread().getName()+" set value :" + ThreadLocalPool.tl.get());
		}
	}
}

输出结果:

线程A set value :1
线程D set value :4
线程C set value :3
线程B set value :2
线程C set value :7
线程D set value :6
线程A set value :5
线程D set value :10
线程C set value :9
线程B set value :8
线程B set value :12
线程A set value :11

从结果看出,每个线程都有自己的String,并且不会相互影响,用一个ThreadLocal也可以多次set一个数据,set仅仅表示的线程TheadLocal.ThreadLocalMap中table某一个位置value覆盖,而且对于同一个ThreadLocal对象而言,set后,table绝不会多出一个数据.

给ThreadLocal设置初始值,解决get返回null的问题

public static final ThreadLocal<String> tl = new ThreadLocal<String>(){	
		protected String initialValue() {
			return "我是get时候为null时候的默认值";
		};
	};

对initialValue方法进行重写

InheritableThreadLocal实现父线程向子线程传递值

package com.ftf.thread.test;

import java.util.Date;

public class InheritableTest extends InheritableThreadLocal<String> {
	@Override
	protected String initialValue() {
		return new Date().getTime()+"";
	}
	/*@Override
	protected String childValue(String parentValue) {
		return "子线程加上的值";
	}*/
	public static void main(String[] args) throws InterruptedException {
		Tools.it.set("我是父线程定义的值");
		for(int i=0;i<3;i++){
			System.out.println("Main线程中值:"+Tools.it.get());
			Thread.sleep(1000);
		}
		Thread t = new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("子线程中获取到的值"+Tools.it.get());
			}
		});
	  t.start();
	}
}
class Tools {
	public static final InheritableTest it = new InheritableTest();
}

输出结果

Main线程中值:我是父线程定义的值
Main线程中值:我是父线程定义的值
Main线程中值:我是父线程定义的值
子线程中获取到的值我是父线程定义的值

main线程是父线程,里面启动子线程Thread,从结果看出,子线程获取到的值从父线程而来,而不是初始值

* 将上面的ChildValue方法放开,就能定义再次修改继承过来的值

Main线程中值:我是父线程定义的值
Main线程中值:我是父线程定义的值
Main线程中值:我是父线程定义的值
子线程中获取到的值子线程加上的值

ThreadLocal再总结

1. TheadLocal可以看做是一个抽屉,每个线程都能向里面放数据,取数据,不会相互干扰

2. 同步和ThreadLocal是解决多线程中数据访问问题的两种思路,前者是数据共享,后者是数据隔离

3. 同步是一种时间换空间的思想,ThreadLocal是一种空间换时间的思想

4. ThreadLocal既然与线程相关,对于java web而言,ThreadLocal设置的是只在一次请求中有效,是不是和request很像?因为request里面的内容只是在一次请求中有效,对比一下两者的区别:

* ThreadLocal只能去设置一个值,因为每次set值的时候,会找到threadLocal相同的entry,进行覆盖

,而request每次可以设置多个值,是因为key-value的结构

参考博客:

http://www.cnblogs.com/xrq730/p/4854820.html

《Java多线程核心技术》



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值