zoukankan      html  css  js  c++  java
  • SimpleDateFormat非线程安全

    类SimpleDateFormat主要负责日期的格式化和转换,但是在多线程的环境中,使用此类容易造成数据转换和处理不正确,因为SimpleDateFormat类并不是线程安全的。

    • 1简单示例,出现异常
    package com.test.test4;
    
    
    import java.text.SimpleDateFormat;
    
    /**
     * SimpleDateFormat非线程安全
     * Created by admin on 2018/12/18.
     */
    public class Test {
    
        public static void main(String[] args) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String[]dataStringArray = new String[]{"2000-01-01","2000-01-02","2000-01-03","2000-01-04","2000-01-05"};
            MyThread[] threadArray = new MyThread[5];
            for (int i=0;i<5;i++) {
                threadArray[i] = new MyThread(sdf,dataStringArray[i]);
            }
            for (int i=0;i<5;i++) {
                threadArray[i].start();
            }
        }
    
    }
    
    
    
    package com.test.test4;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by admin on 2018/12/18.
     */
    public class MyThread extends Thread {
    
        private SimpleDateFormat sdf;
    
        private String dateString;
    
        public MyThread(SimpleDateFormat sdf,String dateString){
            super();
            this.sdf = sdf;
            this.dateString = dateString;
        }
        @Override
        public void run(){
            try {
                Date dateRef = sdf.parse(dateString);
                String newDateString = sdf.format(dateRef).toString();
                if (!newDateString.equals(dateString)) {
                    System.out.println("ThreadName="+this.getName()+"报错了 日期字符串:"+dateString+"转换成的日期为"+newDateString);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    •   运行结果
    ThreadName=Thread-4报错了 日期字符串:2000-01-05转换成的日期为0001-01-02
    ThreadName=Thread-2报错了 日期字符串:2000-01-03转换成的日期为0001-01-02
    ThreadName=Thread-0报错了 日期字符串:2000-01-01转换成的日期为0001-01-02
    ThreadName=Thread-3报错了 日期字符串:2000-01-04转换成的日期为0001-01-02
    
    Process finished with exit code 0
    
    •   解决异常办法一:解决处理错误的原理是创建了多个SimpleDateFormat
    public class Test {
    
        public static void main(String[] args) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String[]dataStringArray = new String[]{"2000-01-01","2000-01-02","2000-01-03","2000-01-04","2000-01-05"};
            MyThread[] threadArray = new MyThread[5];
            for (int i=0;i<5;i++) {
                threadArray[i] = new MyThread(sdf,dataStringArray[i]);
            }
            for (int i=0;i<5;i++) {
                threadArray[i].start();
            }
        }
    
    }
    
    
    package com.test.formatOk1;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by admin on 2018/12/18.
     */
    public class DateTools {
    
        public static Date parse(String formatPattern, String dataString) throws ParseException{
            return new SimpleDateFormat(formatPattern).parse(dataString);
        }
    
        public static String format(String formatPattern,Date date){
            return new SimpleDateFormat(formatPattern).format(date).toString();
        }
    
    }
    
    package com.test.formatOk1;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by admin on 2018/12/18.
     */
    public class MyThread extends Thread {
    
        private SimpleDateFormat sdf;
    
        private String dateString;
    
        public MyThread(SimpleDateFormat sdf,String dateString){
            super();
            this.sdf = sdf;
            this.dateString = dateString;
        }
        @Override
        public void run(){
            try {
                Date dateRef = DateTools.parse("yyyy-MM-dd",dateString);
                String newDateString = DateTools.format("yyyy-MM-dd",dateRef).toString();
                if (!newDateString.equals(dateString)) {
                    System.out.println("ThreadName="+this.getName()+"报错了 日期字符串:"+dateString+"转换成的日期为"+newDateString);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
    }
    

      解决异常办法二:ThreadLocal类能使线程绑定到指定对象,使用ThreadLocal也可以处理这种错误

    package com.test.formatOk2;
    
    
    import java.text.SimpleDateFormat;
    
    /**
     * SimpleDateFormat非线程安全
     * Created by admin on 2018/12/18.
     */
    public class Test {
    
        public static void main(String[] args) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String[]dataStringArray = new String[]{"2000-01-01","2000-01-02","2000-01-03","2000-01-04","2000-01-05"};
            MyThread[] threadArray = new MyThread[5];
            for (int i=0;i<5;i++) {
                threadArray[i] = new MyThread(sdf,dataStringArray[i]);
            }
            for (int i=0;i<5;i++) {
                threadArray[i].start();
            }
        }
    
    }
    
    
    package com.test.formatOk2;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by admin on 2018/12/18.
     */
    public class DateTools {
    
        private static ThreadLocal<SimpleDateFormat> t1 = new ThreadLocal<SimpleDateFormat>();
        public static SimpleDateFormat getSimpleDateFormat(String datePattern){
            SimpleDateFormat sdf = null;
            sdf = t1.get();
            if (sdf == null) {
                sdf = new SimpleDateFormat(datePattern);
                t1.set(sdf);
            }
            return sdf;
        }
    
    }
    
    
    package com.test.formatOk2;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by admin on 2018/12/18.
     */
    public class MyThread extends Thread {
    
        private SimpleDateFormat sdf;
    
        private String dateString;
    
        public MyThread(SimpleDateFormat sdf,String dateString){
            super();
            this.sdf = sdf;
            this.dateString = dateString;
        }
        @Override
        public void run(){
            try {
                Date dateRef = DateTools.getSimpleDateFormat("yyyy-MM-dd").parse(dateString);
                String newDateString = DateTools.getSimpleDateFormat("yyyy-MM-dd").format(dateRef).toString();
                if (!newDateString.equals(dateString)) {
                    System.out.println("ThreadName="+this.getName()+"报错了 日期字符串:"+dateString+"转换成的日期为"+newDateString);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
    }
    

      

  • 相关阅读:
    Laravel模型间关系设置分表方法详解
    11个PHP程序员最常犯的MySQL错误
    教你使用swoole监听redis数据
    使用 Docker 环境来开发 PHP,Laradock 系列 1
    tp5 workerman安装不上解决方法
    一种颗粒度很小的 Laravel 路由文件划分方式
    VT 调试环境搭建
    masm32基本配置与写出第一个汇编程序
    [debug] 解决pycharm中无法import自己建立的模块问题
    《Windows内核安全与驱动开发》 7.1&7.2&7.3 串口的过滤
  • 原文地址:https://www.cnblogs.com/airycode/p/10135136.html
Copyright © 2011-2022 走看看