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

      

  • 相关阅读:
    Visual Studio 连接不上NuGet 官方程序包源的解决办法
    Microsoft Toolkit 2.5下载 – 一键激活Windows 8.1/2012 R2/Office 2013
    Intel® Ethernet Connection I217-V 网卡驱动(win10 ,2012)
    flashfxp3.41中文版注册码:(适合最新版本)
    Fiddler对安卓应用手机抓包图文教程
    网址检查器1.0
    Win10打不开chm文件的解决办法
    Android HTTP通讯
    对Android开发者有益的40条优化建议
    IIS下PHP的三种配置方式比较
  • 原文地址:https://www.cnblogs.com/airycode/p/10135136.html
Copyright © 2011-2022 走看看