前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA日期安全格式化之SimpleDateFormat和jodaTime,DateTimeFormatter

JAVA日期安全格式化之SimpleDateFormat和jodaTime,DateTimeFormatter

原创
作者头像
开源日记
修改2021-01-29 10:15:54
5670
修改2021-01-29 10:15:54
举报
文章被收录于专栏:JVMGCJVMGCJVMGC

SimpleDateFormat线程不安全的日期格式化库

SimpleDateFormatJAVA提供的一个日期转换类。

package com.rumenz.task;

import java.text.SimpleDateFormat;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

//线程不安全
public class DataFormat {

    private static SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
    private static Integer clientTotal=5000;
    private static Integer threadTotal=200;

    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore=new Semaphore(threadTotal);
        final CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
        for (int i = 0; i <clientTotal ; i++) {
            executorService.execute(()->{
                try{
                    semaphore.acquire();
                    update();
                    semaphore.release();
                }catch (Exception e){
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            });

        }
        countDownLatch.await();
        executorService.shutdown();


    }

    private static void update() {
        try{
            simpleDateFormat.parse("20200115");
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

运行的时候会报错,线程不安全

java.lang.NumberFormatException: For input string: "E152"
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.rumenz.task.DataFormat.update(DataFormat.java:47)
	at com.rumenz.task.DataFormat.lambda$main$0(DataFormat.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

如果要使用SimpleDateFormat可以将其做成局部变量,这样在多线程环境下就不会出现线程安全问题。或者使用synchronized给方法加锁。

jodaTime 线程安全的格式化库

引入依赖

<dependency>
  <groupId>joda-time</groupId>
  <artifactId>joda-time</artifactId>
  <version>2.9.9</version>
</dependency>
package com.keytech.task;

import org.joda.time.DateTime;

import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

//线程安全
public class DataFormat1 {

    public static Integer clientTotal=5000;
    public static Integer threadTotal=200;
    private static DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyyMMdd");

    public static void main(String[] args)  throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore=new Semaphore(threadTotal);
        final CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
        for (int i = 0; i < clientTotal; i++) {
            executorService.execute(()->{
                try{
                    semaphore.acquire();
                    update();
                    semaphore.release();

                }catch (Exception e){
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            });

        }
        countDownLatch.await();
        executorService.shutdown();
    }

    private static void update() {
        DateTime dateTime = DateTime.parse("20200115").toDateTime();
        System.out.println(dateTime);
    }
}

DateTimeFormatter JAVA8中线程安全的日期转换类

package com.keytech.task;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

//线程安全
public class DateFormat2 {

    public static Integer clientTotal=5000;
    public static Integer threadTotal=200;
    private  static final  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore=new Semaphore(threadTotal);
        final CountDownLatch countDownLatch=new CountDownLatch(clientTotal);

        for (int i = 0; i < clientTotal; i++) {
            try{
                semaphore.acquire();
                update();
                semaphore.release();
            }catch (Exception e){
                e.printStackTrace();
            }
            countDownLatch.countDown();

        }

        countDownLatch.await();
        executorService.shutdown();

    }

    private static void update() {
        LocalDate localDate = LocalDate.parse("20200115", formatter);
        System.out.println(localDate);

    }
}

JAVA8中自带,直接可以使用,不需要引入其它的库。

wx.jpg
wx.jpg

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SimpleDateFormat线程不安全的日期格式化库
  • jodaTime 线程安全的格式化库
    • 引入依赖
    • DateTimeFormatter JAVA8中线程安全的日期转换类
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档