至于说Date线程不安全,get,set的肯定在多线程的时候容易出现问题,不过set方法已经都@Deprecated废弃了。当然不是因为线程安全问题废弃的,是因为有了更好的替代
Calendar.set(Calendar.DAY_OF_MONTH, int date)
不过感觉还是不如这个更清晰明了
LocalDate.of(2019,1,12);
2.1 SimpleDateFormat的线程安全性
参考:深入理解Java:SimpleDateFormat安全的时间格式化
在一定负载情况下,SimpleDateFormat会出问题的。简单测试一下
package open.note; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; public class UnSafeTest { private static String time = "2019-01-11 11:11:11"; private static long timestamp = 1547176271000L; private static LocalDateTime dateTime = LocalDateTime.of(2019,1,11,11,11,11); private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static void main(String[] args) { dateFormatTest((obj)->{ try { Date date = dateFormat.parse(time); if (date.getTime() != timestamp){ System.out.println(date); } } catch (Exception e) { System.out.println(e.getMessage()); } }); System.out.println("---------------"); dateFormatTest((obj)->{ try { LocalDateTime dateTime = LocalDateTime.parse(time,formatter); if (!dateTime.isEqual(UnSafeTest.dateTime)){ System.out.println(dateTime); } } catch (Exception e) { System.out.println(e.getMessage()); } }); } private static void dateFormatTest(Consumer runnable){ CountDownLatch countDownLatch = new CountDownLatch(1000); for (int i = 0; i < 1000; i++) { new Thread(()->{ runnable.accept(null); countDownLatch.countDown(); }).start(); } try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } }输出结果
multiple points multiple points empty String Sat Jan 11 11:11:11 CST 111 Fri Jan 04 11:11:11 CST 2019 For input string: "" Mon Dec 31 11:11:11 CST 2018 Mon Dec 31 11:11:11 CST 2018 For input string: "" Tue Jan 11 11:11:11 CST 42101测试过程中,SimpleDateFormat 1000个线程里,有5次,时间解析错了,5次异常了(时间错了,比抛出异常还可怕)
DateTimeFormatter只是对比参考一下,未出现异常(人家已经声明是线程安全了...)
当然SimpleDateFormat线程不安全应该人尽皆知的,但依然有不安全的使用,但每次使用都new一个实例,当负载大的时候也不好。所以一个线程一个SimpleDateFormat实例应该可以的。
最后
java8 对时间操作的类还有很多 到java.time包下去看看,以后总会用得到的地方。
Clock:时钟,比如获取目前美国纽约的时间。
Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx