码迷,mamicode.com
首页 > 其他好文 > 详细

时间处理

时间:2019-09-11 21:33:41      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:protect   回收   幻读   for   多线程   EDA   exce   缺点   cat   

SimpleDateFormat 的线程安全性问题

public class DateFormat {
    // 多线程下存在问题,同步锁可解决
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static class Task implements Runnable {
        @Override
        public void run() {
            try {
                System.out.println(simpleDateFormat.parse("2019-06-01 01:01:02"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    private static void threadTest() {
        ExecutorService executorService= Executors.newFixedThreadPool(3);
        Task task = new Task();
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        Thread t3 = new Thread(task);
        Thread t4 = new Thread(task);
        Thread t5 = new Thread(task);
        executorService.execute(t1);
        executorService.execute(t2);
        executorService.execute(t3);
        executorService.execute(t4);
        executorService.execute(t5);
        executorService.shutdown();
    }

    public static void main(String[] args) {
        threadTest();
    }
}

  SimpleDateFormat类内部有一个Calendar对象引用,用来储存这个SimpleDateFormat相关的日期信息,多线程下会共享这个Calendar引用,会导致出现幻读成员变量的现象

 

解决办法:

1、将SimpleDateFormat定义成局部变量。

缺点:每调用一次方法就会创建一个SimpleDateFormat对象,方法结束又要作为垃圾回收。

2、方法加同步锁synchronized,在同一时刻,只有一个线程可以执行类中的某个方法。

缺点:性能较差,每次都要等待锁释放后其他线程才能进入。

3、使用第三方库joda-time,由第三方考虑线程不安全的问题。(可以使用)

4、使用ThreadLocal:每个线程拥有自己的SimpleDateFormat对象。(推荐使用)

 

使用ThreadLocal方式,如下:

private static final ThreadLocal<SimpleDateFormat> df = new ThreadLocal<SimpleDateFormat>() {
   @Override
   protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd");
    }
};

private static class TaskLocal implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println(df.get().parse("2019-06-01 01:01:02"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

  

JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替Simpledateformatter

public static void main(String[] args) {
    LocalDateTime arrivalDate  = LocalDateTime.now();
    DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String landing = arrivalDate.format(format);
    System.out.println(landing);
}

  

时间处理

标签:protect   回收   幻读   for   多线程   EDA   exce   缺点   cat   

原文地址:https://www.cnblogs.com/jhin-wxy/p/11507702.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!