ThreadLocal线程局部变量的使用

普通的日期装换类:

/**
 * 不使用ThreadLocal进行时间装换时出现的问题
 *     多个线程共同使用一个sdf对象,SimpleDataFormat内部维护着一个Caledar对象
 *     Caledar对象存储着parse(dateStr)或format(date)中dateStr、date的信息
 *     Caledar执行两个操作
 *       claer(); 清楚维护的date或dateStr的信息
 *       getTime(); 获取date
 *
 *     当所有的线程共用一个SimpleDateFormat对象时,使用同一个Calendar引用
 *     此时,出现问题:
 *     线程A调用parse(), 并没有getTime(),此时轮到了线程B执行parse(),线程B执行完后也clear(),线程A, getTime()
 *     最后得到的是线程B的时间
 *
 *     ThreadLocal: 解决了static修饰的共享变量内部操作不一致的问题。
 */
public class NormalParseDate implements Runnable{
    /**
     * 多个线程共享的变量
     */
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");

    int i = 0;

    public NormalParseDate(int i) {
        this.i = i;
    }

    /**
     * 日期装换方法
     */

    @Override
    public void run() {
        try {
            //所有的线程使用同一个sdf
            Date date = sdf.parse("2017-08-02 11:22:"+ i % 60);
            System.out.println(i+" : "+date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    /**
     * 创建线程
     */
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        for(int i = 0; i < 100; i++){
            executor.execute(new NormalParseDate(i));
        }
    }
}

结果:

Exception in thread "pool-1-thread-6" java.lang.NumberFormatException: empty String
97 : Mon Jan 02 11:22:37 CST 2017
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)

使用ThreadLocal的日期转换类:
~~~

/**

  • 使用ThreadLocal线程局部变量来解决线程间共享变量内部操作不一致问题
    */
    public class ThreadLocalParseData implements Runnable{
    private static ThreadLocal threadLocal = new ThreadLocal<>();
    int i = 0;

    public ThreadLocalParseData(int i) {
    this.i = i;
    }

    @Override
    public void run() {
    //判断当前线程是否有SimpleDateFormat对象,有则使用,没有则创建
    if(threadLocal.get() == null){
    //如果没有就给当前线程创建一个
    threadLocal.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }
    //有,则直接使用
    try {
    Date date = threadLocal.get().parse("2017-2-21 14:29:" + i % 60);
    System.out.println(i+":"+date);
    } catch (ParseException e) {
    e.printStackTrace();
    }
    }

    public static void main(String[] args) {
    //创建线程对象,每个线程都有一个SimpleDateFormat对象
    ExecutorService executor = Executors.newFixedThreadPool(10);
    for(int i = 0; i < 100; i++){
    executor.execute(new ThreadLocalParseData(i));
    }
    }
    }

猜你喜欢

转载自www.cnblogs.com/Auge/p/11772569.html