7.17 线程:ThreadLocal

线程:ThreadLocal

简介

  1. 在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程。
  2. ThreadLocal能够放一个线程级别的变量,其本身能够被多个线程共享使用,并且又能够达到线程安全的目的。说白了,ThreadLocal就是想在多线程环境下去保证成员变量的安全,常用的方法,就是get/set/initialValue()方法。
  3. JDK建议ThreadLocal定义为private static
  4. ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的方法都可以非常方便地访问这些资源。
    (1)Hibernate的Session工具类HibernateUtil
    (2)通过不同的线程对象设置Bean属性,保证各个线程Bean对象的独立性。

测试

  1. 基本使用方法
    code:
/**
 * ThreadLocal:每个线程自身的存储本地、局部区域
 * get/set/initValue
 * @author dxt
 *
 */
public class ThreadLocalTest01 {
	//创建一个线程空间, 每个线程都在里面有一个只有自己可以访问的"保险箱"
	//public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
	
	//2. 更改线程空间的初始值,要重写initialValue()方法
	public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
		protected Integer initialValue(){
			return 200;	//初始值由null变为200
		}
	};
	
	public static void main(String[] args){
		//1. 打印 主线程 的初始值, 因为是Integer而不是int,所以会打印null,而不是0
		System.out.println(Thread.currentThread().getName() + "--" + threadLocal.get());
		
		//3. 设置初始化值
		threadLocal.set(100);
		System.out.println(Thread.currentThread().getName() + "--" + threadLocal.get());
		
		//4. 在main线程外,建立新的线程,两个线程间的值互不影响
		new Thread(new MyRun()).start();
		//5. 每个线程在ThreadLocal内有自己独立的空间
		new Thread(new MyRun()).start();
	}
	/**
	 * 静态内部类
	 * @author dxt
	 *
	 */
	public static class MyRun implements Runnable{
		public void run(){
			threadLocal.set((int)(Math.random()*100));
			System.out.println(Thread.currentThread().getName() + "--" + threadLocal.get());
		}
	}
}

result:
res1
2. 每个线程有自己的存储区域
code:

/**
 * 每个线程有自己的存储区域
 * @author dxt
 *
 */
public class ThreadLocalTest02 {
	//创建线程空间
	public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
		protected Integer initialValue(){
			return 1;	//将数据初始化为1,可以认为每个线程都有一个属于自己的1
		}
	};
	
	public static void main(String[] args){
		//建立5个线程
		for(int i=0; i<5; i++){
			new Thread(new MyRun()).start();
		}
	}
	
	public static class MyRun implements Runnable{
		public void run(){
			Integer left = threadLocal.get();
			System.out.println(Thread.currentThread().getName() + " 得到了"+ left+"个苹果");
			threadLocal.set(left-1);
			System.out.println(Thread.currentThread().getName() + " 还剩下"+ threadLocal.get()+"个苹果");
		}
	}
}

result:
res2
3. 分析上下文
code:

/**
 * 分析ThreadLocal的上下文, 环境
 * @author dxt
 *
 */
public class ThreadLocalTest03 {
	//创建线程空间
	public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
		protected Integer initialValue(){
			return 1;	//将数据初始化为1,可以认为每个线程都有一个属于自己的1
		}
	};
	
	public static void main(String[] args){
		new Thread(new MyRun()).start();
	}
	
	public static class MyRun implements Runnable{
		public MyRun(){
			threadLocal.set(100);	//是对main线程进行更改
			//输出调用MyRun()构造函数的线程的信息
			System.out.println(Thread.currentThread().getName()+"--"+threadLocal.get());
		}
		
		public void run(){
			System.out.println(Thread.currentThread().getName()+"--"+threadLocal.get());
		}
	}
}

result:
res3
4. InheritableThreadLocal
code:

/**
 * InheitableThreadLocal:继承上下文环境的数据,复制一份数给子线程,在子线程中可以更改
 * 但不影响原数据 
 * @author dxt
 *
 */
public class ThreadLocalTest04 {
	public static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<Integer>();
	
	public static void main(String[] args){
		threadLocal.set(2);
		System.out.println(Thread.currentThread().getName() + "  " + threadLocal.get());
		
		new Thread(new Runnable(){
			public void run(){	//若是ThreadLocal会是null
				System.out.println(Thread.currentThread().getName() + "  " + threadLocal.get());
			}
		}).start();
		
	}
}

result:
res4

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值