java 多线程:线程安全问题,示例DateFormat多线程执行冲突解决方案ThreadLocal、方法内变量

SimpleDateFormat多线程中执行报错

  • java.lang.NumberFormatException: For input string: ""  
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    /**
     * @ClassName VarNotSafeDateFormat
     * @projectName: object1
     * @author: Zhangmingda
     * @description: XXX
     * date: 2021/4/26.
     */
    public class VarNotSafeDateFormat {
        private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); //使用共享的共享对象可能报错
        private static class DateFormatTransfer extends Thread{
            private String dateStr;
    
            public DateFormatTransfer(String dateStr) {
                this.dateStr = dateStr;
            }
    
            @Override
            public void run() {
    //            DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");  方法内变量安全,每个线程执行方法的时候独立创建实例
                try {
                    Date date = DATE_FORMAT.parse(dateStr);
                    String stringDateAfterTrans = DATE_FORMAT.format(date);
                    System.out.println(dateStr + "转换后:" + stringDateAfterTrans);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            List<String> dates = Arrays.asList("2021-04-21","2021-04-22","2021-04-23","2021-04-24","2021-04-25",
                    "2021-04-26","2021-04-27","2021-04-28","2021-04-29","2021-04-30");
            Set<Thread> threads = new HashSet<>();
            dates.forEach(dateStr ->{
    //            new DateFormatTransfer(dateStr).start();
                threads.add(new DateFormatTransfer(dateStr));
            });
            threads.forEach(thread -> thread.start());
        }
    }

 

 

 

ThreadLocal 变量 解决方案:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName VarNotSafeDateFormat
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/4/26.
 */
public class VarNotSafeDateFormat {

    /**
     * ThreadLocal 线程安全变量,和方法变量异曲同工之妙,实际都创建了不同的子实例用
     */
    private static final ThreadLocal<DateFormat> DATE_FORMAT_THREAD_LOCAL = new ThreadLocal<>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    private static class DateFormatTransfer extends Thread{
        private String dateStr;

        public DateFormatTransfer(String dateStr) {
            this.dateStr = dateStr;
        }

        @Override
        public void run() {
//            DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");  方法内变量安全,每个线程执行方法的时候独立创建实例
            try {
                Date date = DATE_FORMAT_THREAD_LOCAL.get().parse(dateStr);
                String stringDateAfterTrans = DATE_FORMAT_THREAD_LOCAL.get().format(date);
                System.out.println(dateStr + "转换后:" + stringDateAfterTrans);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        List<String> dates = Arrays.asList("2021-04-21","2021-04-22","2021-04-23","2021-04-24","2021-04-25",
                "2021-04-26","2021-04-27","2021-04-28","2021-04-29","2021-04-30");
        Set<Thread> threads = new HashSet<>();
        dates.forEach(dateStr ->{
            threads.add(new DateFormatTransfer(dateStr));
        });
        threads.forEach(thread -> thread.start());
    }
}

 

 

 

 

 

posted on 2021-04-26 15:49  zhangmingda  阅读(270)  评论(0编辑  收藏  举报

导航