ThreadLocal的两个作用:
1.让某个需要用到的对象在线程间隔离(每个线程都有自己独立的对象)
2.在任何方法中都可以轻松获取该对象
场景一:initialValue
在ThreadLocal第一次get的时候把对象给初始化出来,对象的初始化时机可以由我们控制
场景二:set
如果需要保存到ThreadLocal里的对象的生成的时机不由我们随意控制,例如拦截器生成的用户信息,用ThreadLocal.set直接放到我们的ThreadLocal中去,以便后续使用
使用ThreadLocal带来的好处:
(1)达到线程安全
(2)不需要加锁,提高执行效率
(3)更高效的利用内存,节省开销:相比于每个任务都新建一个SimpleDateFormat,显然使用ThreadLocal可以节省内存和开销
(4)免去传参的繁琐:无论场景一的工具类,还是场景二的用户名,都可以在任何地方直接通过ThreadLocal拿到,再也不需要每次都传同样的参数。ThreadLocal使得代码耦合度更低, 更优雅
public class ThreadLocalDemo01 {
public static ExecutorService threadPool = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
int finalI = i;
threadPool.submit(()->{
String date = new ThreadLocalDemo01().date(finalI);
System.out.println(date);
});
}
threadPool.shutdown();
}
public String date(int seconds){
Date date = new Date(1000*seconds);
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
SimpleDateFormat dateFormat = ThreadSafeFormatter.dateFormatThreadLocal.get();
return dateFormat.format(date);
}
}
class ThreadSafeFormatter{
public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = ThreadLocal.withInitial(()-> new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
}