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

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

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

  1. package com.rumenz.task;
  2. import java.text.SimpleDateFormat;
  3. import java.util.concurrent.CountDownLatch;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.Semaphore;
  7. //线程不安全
  8. public class DataFormat {
  9. private static SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
  10. private static Integer clientTotal=5000;
  11. private static Integer threadTotal=200;
  12. public static void main(String[] args) throws Exception{
  13. ExecutorService executorService = Executors.newCachedThreadPool();
  14. final Semaphore semaphore=new Semaphore(threadTotal);
  15. final CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
  16. for (int i = 0; i <clientTotal ; i++) {
  17. executorService.execute(()->{
  18. try{
  19. semaphore.acquire();
  20. update();
  21. semaphore.release();
  22. }catch (Exception e){
  23. e.printStackTrace();
  24. }
  25. countDownLatch.countDown();
  26. });
  27. }
  28. countDownLatch.await();
  29. executorService.shutdown();
  30. }
  31. private static void update() {
  32. try{
  33. simpleDateFormat.parse("20200115");
  34. }catch (Exception e){
  35. e.printStackTrace();
  36. }
  37. }
  38. }

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

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

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

jodaTime 线程安全的格式化库

引入依赖

  1. <dependency>
  2. <groupId>joda-time</groupId>
  3. <artifactId>joda-time</artifactId>
  4. <version>2.9.9</version>
  5. </dependency>
  1. package com.keytech.task;
  2. import org.joda.time.DateTime;
  3. import java.time.format.DateTimeFormatter;
  4. import java.time.temporal.TemporalAccessor;
  5. import java.util.Date;
  6. import java.util.concurrent.CountDownLatch;
  7. import java.util.concurrent.ExecutorService;
  8. import java.util.concurrent.Executors;
  9. import java.util.concurrent.Semaphore;
  10. //线程安全
  11. public class DataFormat1 {
  12. public static Integer clientTotal=5000;
  13. public static Integer threadTotal=200;
  14. private static DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyyMMdd");
  15. public static void main(String[] args) throws Exception{
  16. ExecutorService executorService = Executors.newCachedThreadPool();
  17. final Semaphore semaphore=new Semaphore(threadTotal);
  18. final CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
  19. for (int i = 0; i < clientTotal; i++) {
  20. executorService.execute(()->{
  21. try{
  22. semaphore.acquire();
  23. update();
  24. semaphore.release();
  25. }catch (Exception e){
  26. e.printStackTrace();
  27. }
  28. countDownLatch.countDown();
  29. });
  30. }
  31. countDownLatch.await();
  32. executorService.shutdown();
  33. }
  34. private static void update() {
  35. DateTime dateTime = DateTime.parse("20200115").toDateTime();
  36. System.out.println(dateTime);
  37. }
  38. }

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

  1. package com.keytech.task;
  2. import java.time.LocalDate;
  3. import java.time.format.DateTimeFormatter;
  4. import java.util.concurrent.CountDownLatch;
  5. import java.util.concurrent.ExecutorService;
  6. import java.util.concurrent.Executors;
  7. import java.util.concurrent.Semaphore;
  8. //线程安全
  9. public class DateFormat2 {
  10. public static Integer clientTotal=5000;
  11. public static Integer threadTotal=200;
  12. private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
  13. public static void main(String[] args) throws Exception{
  14. ExecutorService executorService = Executors.newCachedThreadPool();
  15. final Semaphore semaphore=new Semaphore(threadTotal);
  16. final CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
  17. for (int i = 0; i < clientTotal; i++) {
  18. try{
  19. semaphore.acquire();
  20. update();
  21. semaphore.release();
  22. }catch (Exception e){
  23. e.printStackTrace();
  24. }
  25. countDownLatch.countDown();
  26. }
  27. countDownLatch.await();
  28. executorService.shutdown();
  29. }
  30. private static void update() {
  31. LocalDate localDate = LocalDate.parse("20200115", formatter);
  32. System.out.println(localDate);
  33. }
  34. }

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

返回笔记列表
入门小站