对ThreadLocal的理解、简单应用(二)

其他理解:
不应该只把它当作一个传参工具,它本身是为线程安全和某些特定场景的问题而设计的。
 
诡异的ThreadLocal最难琢磨的是“ 作用域”,尤其是在代码设计之初非常乱的情况下,假设再添加很多ThreadLocal。系统就会逐渐变成神龙见首不见尾的情况。
使用ThreadLocal,不要简单粗暴地多一个參数就加一个ThreadLocal变量。比如,我们能够设计几种对象来封装入口參数,在接口设计时入口參数都以对象为基础。
 
通过一个简单示例解释怎么应用ThreadLocal:
public class Deomo01 {

	
	
	public static void main(String p[]) {
		
		ThreadLocalString tStringA = new ThreadLocalString("线程A");
		ThreadLocalString tStringB = new ThreadLocalString("线程B");
		ThreadLocalString tStringC = new ThreadLocalString("线程C");
		tStringA.start();
		tStringB.start();
		tStringC.start();
		
	}
	
	public static class ThreadLocalString extends Thread{
		
		
		//线程名称
		private String name ;
		public ThreadLocalString () {};
		public ThreadLocalString(String name) {
			this.name = name;
		}
		@Override
		public void run() {
			for(int i = 0 ; i < 10 ; i++) {
				if(ThreadLocalManager.get() == null) {
					ThreadLocalManager.set(String.valueOf(0));
					System.out.println(name+"-->"+ThreadLocalManager.get());
				}else {
					
					String str = ThreadLocalManager.get();
					ThreadLocalManager.set(String.valueOf(Integer.parseInt(str)+1));
					System.out.println(name+"-->"+ThreadLocalManager.get());
					if(i==6) {
						ThreadLocalManager.remove();
						System.out.println("将当前这个线程的ThreadLocal清除后:"+ThreadLocalManager.get());
					}
				}
			}
		}
	}
}

  

public class ThreadLocalManager {



	private static ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();
	
	public static String get() {
		return myThreadLocal.get();
	}
	
	public static void set(String i) {
		myThreadLocal.set(i);
	}
	
	public static void remove() {
		myThreadLocal.remove();
	}
	
	
	
	
	
}

  

内在原理解释:
ThreadLocal最常见的操作就是set、get、remove三个动作。以下来看看这三个动作究竟做了什么事情:
代码中有两条路径须要追踪,各自是getMap(Thread)和createMap(Thread , T)。首先来看看 getMap(t)操作:

 

这个ThreadLocalMap是ThreadLocal里面的内部类。放在了Thread类里面作为一个私有变量而存在,所以是线程安全的。ThreadLocal本身成为这个Map里面存放的Key,用户输入的值是Value。

代码逻辑:

1.ThreadLocal通过Thread.currentThread()获取当前的线程就能得到这个Map对象。

2.同一时候将自身作为Key发起写入和读取,因为将自身作为Key,所以一个ThreadLocal对象就能存放一个线程中相应的Java对象。通过get也自然能找到这个对象。

再来看看 createMap:

 

将第一个值作为这个Map的初始化值,因为这个Map是线程私有的。不可能有还有一个线程同一时候也在对它做put操作,因此这里的赋值和初始化是绝对线程安全的,也同一时候保证了每个外部写入的值都将写入到Map对象中。
get和remove方法:

ThreadLocal的应用场景举例:

来源: http://www.cnblogs.com/yxysuanfa/p/7125761.html(还包含很多别的扩展知识)

 

猜你喜欢

转载自www.cnblogs.com/wzdnwyyu/p/11162968.html
今日推荐