ThreadLocal的两个作用
    1.让某个需要用到的对象在线程间隔离(每个线程都有自己独立的对象)
    2.在任何方法中都可以轻松获取该对象
    场景一:initialValue
    在ThreadLocal第一次get的时候把对象给初始化出来,对象的初始化时机可以由我们控制
    场景二:set
    如果需要保存到ThreadLocal里的对象的生成的时机不由我们随意控制,例如拦截器生成的用户信息,用ThreadLocal.set直接放到我们的ThreadLocal中去,以便后续使用

    使用ThreadLocal带来的好处
    (1)达到线程安全
    (2)不需要加锁,提高执行效率
    (3)更高效的利用内存,节省开销:相比于每个任务都新建一个SimpleDateFormat,显然使用ThreadLocal可以节省内存和开销
    (4)免去传参的繁琐:无论场景一的工具类,还是场景二的用户名,都可以在任何地方直接通过ThreadLocal拿到,再也不需要每次都传同样的参数。ThreadLocal使得代码耦合度更低, 更优雅

    1. public class ThreadLocalDemo01 {
    2. public static ExecutorService threadPool = Executors.newFixedThreadPool(10);
    3. public static void main(String[] args) {
    4. for (int i = 0; i < 1000; i++) {
    5. int finalI = i;
    6. threadPool.submit(()->{
    7. String date = new ThreadLocalDemo01().date(finalI);
    8. System.out.println(date);
    9. });
    10. }
    11. threadPool.shutdown();
    12. }
    13. public String date(int seconds){
    14. Date date = new Date(1000*seconds);
    15. //SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    16. SimpleDateFormat dateFormat = ThreadSafeFormatter.dateFormatThreadLocal.get();
    17. return dateFormat.format(date);
    18. }
    19. }
    20. class ThreadSafeFormatter{
    21. public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = ThreadLocal.withInitial(()-> new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
    22. }