关于ThreadLocal的第一种用法

来源:4-5 更好的做法

wenjuhe

2020-07-09

package src.threadlocal;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**

  • 描述: 利用ThreadLocal,给每个线程分配自己的dateFormat对象,保证了线程安全,高效利用内存
    */
    public class ThreadLocalNormalUsage05 {

    public static ExecutorService threadPool = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 1000; i++) {
    int finalI = i;
    threadPool.submit(new Runnable() {
    @Override
    public void run() {
    try{
    String date = new ThreadLocalNormalUsage05().date(finalI);
    System.out.println(ThreadSafeFormatter.dateFormatThreadLocal);
    System.out.println(date);
    }finally {
    System.out.println("*******");
    ThreadSafeFormatter.dateFormatThreadLocal.remove();
    System.out.println(ThreadSafeFormatter.dateFormatThreadLocal.get());
    System.out.println("+++++++");
    }

             }
         });
     }
     threadPool.shutdown();
    

    }

    public String date(int seconds) {
    //参数的单位是毫秒,从1970.1.1 00:00:00 GMT计时
    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 = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
};

/*public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal2 = ThreadLocal
        .withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));*/

}

上面是我的代码 我在finally中 将threadlocal删除 为什么 每次打印的还是同一个 对象,这里的删除不对吗

写回答

1回答

悟空

2020-07-09

get源码:

public T get() {
   Thread t = Thread.currentThread();
   ThreadLocalMap map = getMap(t);
   if (map != null) {
       ThreadLocalMap.Entry e = map.getEntry(this);
       if (e != null) {
           @SuppressWarnings("unchecked")
           T result = (T)e.value;
           return result;
       }
   }
   return setInitialValue();
}

所以可以看出,remove后,如果又get,会发现已经为null,就再次新建一个。

0
2
悟空
回复
wenjuhe
不是同一个: public class ThreadLocalNormalUsage066 { public static ThreadLocal dateFormatThreadLocal = new ThreadLocal() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; public static void main(String[] args) throws InterruptedException { try { System.out.println(dateFormatThreadLocal.get()); System.out.println(System.identityHashCode(dateFormatThreadLocal.get())); } finally { System.out.println("*******"); dateFormatThreadLocal.remove(); System.out.println(dateFormatThreadLocal.get()); System.out.println(System.identityHashCode(dateFormatThreadLocal.get())); System.out.println("+++++++"); } } } 用System.identityHashCode这个方法。
2020-07-09
共2条回复

深度解密Java并发工具,精通JUC,成为并发多面手

JUC全方位讲解,构建并发工具类知识体系

1599 学习 · 573 问题

查看课程