多线程与高并发学习笔记(三)

ThreadLocal

ThreadLocal线程局部变量,每个线程都维护一个ThreadLocal相关的地址空间,相当于每个线程都有一个自己的数据保存地,不会互相影响;以空间换时间的策略。

原理分析


分析ThreadLocal源码可知:使用ThreadLocal后,每个线程都维护着一个Map,而Map里存着Entry对象;key为ThreadLocal对象,值为ThreadLocal 的set方法设置的值(即我们保存在ThreadLocal里的值),这中结构意味着在一个线程里同一个ThreadLocal对象只能设置一个值,因为key不可重复;而Map里可存入多个Entry,但是通过不同的ThreadLocal来实现;

Map中存的Entry对象的key是个虚引用,因为虚引用在GC时会回收虚引用所指向的空间。使用虚引用是当我们线程中ThreadLocal对象的引用t1为null时,可以将ThreadLocal对象所占据的内存空间回收,避免内存泄漏,但还是有内存泄漏的危险,当ThreadLocal对象被回收后,key将为null,而原来根据key可找到的value将不能再被访问到,因此在使用ThreadLocal时千万千万要注意当使用完之后一定一定要调用remove() 方法将值移除。
具体的使用如下

import java.util.concurrent.TimeUnit;

public class ThreadLocal {
     
	//volatile static Person p = new Person();
	static ThreadLocal<Person> tl = new ThreadLocal<>();
	
	public static void main(String[] args) {
     
				
		new Thread(()->{
     
			try {
     
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
     
				e.printStackTrace();
			}
			
			System.out.println(tl.get());
		}).start();
		
		new Thread(()->{
     
			try {
     
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
     
				e.printStackTrace();
			}
			tl.set(new Person());
		}).start();
	}
	
	static class Person {
     
		String name = "zhangsan";
	}
}

你可能感兴趣的:(多线程与高并发,多线程,java)