ThreadLocal_及其机制

一:ThreadLocal类的例子:

某一线程中的局部变量会被其他线程所改写,所以有了ThreadLocal类,可以用这个类来保存局部变量,以保证局部变量的安全!

以下两个例子其中之一使用了ThreadLocal类,另一个未用,注意观察其结果的不同:

class UnsafeTask implements Runnable{
	private Date startDate;
	@Override
	public void run(){
		startDate=new Date();
		System.out.printf("Starting Thread: %s:%s\n",Thread.currentThread().getId(),startDate);
		try {
			TimeUnit.SECONDS.sleep((long) Math.rint(Math.random()*10));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.printf("Thread Finished: %s:%s\n", Thread.currentThread().getId(),startDate);
	}
}
public class Test_UnsafeTask{
	public static void main(String[] args){
		UnsafeTask task=new UnsafeTask();
		for(int i=0;i<10;i++){
			Thread thread=new Thread(task);
			thread.start();
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
结果:
Starting Thread: 9:Tue Oct 14 20:31:36 CST 2014
Starting Thread: 10:Tue Oct 14 20:31:38 CST 2014
Thread Finished: 9:Tue Oct 14 20:31:38 CST 2014
Starting Thread: 11:Tue Oct 14 20:31:40 CST 2014
Thread Finished: 10:Tue Oct 14 20:31:40 CST 2014
Thread Finished: 11:Tue Oct 14 20:31:40 CST 2014

public class Test_SafeTask {
	public static void main(String[] args) {
		SafeTask task = new SafeTask();
		for (int i = 0; i < 3; i++) {
			Thread thread=new Thread(task);
			thread.start();
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class SafeTask implements Runnable {
	// 线程局部变量机制解决局部变量不安全的特性
	private static ThreadLocal<Date> startDate = new ThreadLocal<Date>() {
		protected Date initialValue() {
			return new Date();
		}
	};

	@Override
	public void run() {
		System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread()
				.getId(), startDate.get());
		try {
			TimeUnit.SECONDS.sleep(Math.round(Math.random() * 10));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread()
				.getId(), startDate.get());
	}
}
其结果:

Starting Thread: 9 : Tue Oct 14 20:33:02 CST 2014
Thread Finished: 9 : Tue Oct 14 20:33:02 CST 2014
Starting Thread: 10 : Tue Oct 14 20:33:04 CST 2014
Starting Thread: 11 : Tue Oct 14 20:33:06 CST 2014
Thread Finished: 11 : Tue Oct 14 20:33:06 CST 2014
Thread Finished: 10 : Tue Oct 14 20:33:04 CST 2014
二:ThreadLocal类中的主要方法:

1.泛化的无参构造器,

2.

大家看看吧,不解释了,

3.ThreadLocal有一个静态的内部类ThreadLocalMap,通过这个map对线程中的局部变量进行保存,其key为当前线程的id,value既是你所保存的变量,即初始化,改,查,移除都必须通过这个Thread.currentThread().getId()的id进行,从而保证了局部变量的安全。我们只看下set(T value)的源码就行:

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

4.ThreadLocal这个类是 @author  Josh Bloch and Doug Lea写的,大家可以去百度下这个作者。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值