SimpleDateFormat
线程不安全的日期格式化库
SimpleDateFormat
是JAVA
提供的一个日期转换类。
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中自带,直接可以使用,不需要引入其它的库。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。