• 时间处理


    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);
    }
    

      

  • 相关阅读:
    利用GetCharWidth32获取字符串宽度
    活着,就一直在忙碌,从未有停歇。
    AutoMapper 创建嵌套对象映射(原创)
    停下,为了更好的前行---给自己画像
    iOS开发——真机调试证书—发布证书
    iOS开发——免证书调试(Xcode7,iOS9)
    iOS开发——常用字符串string相关方法和处理
    iOS开发——图文混排(CoreText—TextKit)
    iOS开发——语言适配——中文英文
    iOS开发——富文本——自定义字体
  • 原文地址:https://www.cnblogs.com/jhin-wxy/p/11507702.html
Copyright © 2020-2023  润新知