千家信息网

如何使用java8的格式化Date

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,这篇文章主要讲解了"如何使用java8的格式化Date",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何使用java8的格式化Date"吧!Simpl
千家信息网最后更新 2024年11月26日如何使用java8的格式化Date

这篇文章主要讲解了"如何使用java8的格式化Date",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何使用java8的格式化Date"吧!

SimpleDateFormat 线程不安全

众所周知 SimpleDateFormat 线程不安全,不少朋友被其坑过。

public class ExampleClass {        private static final Pattern dateCreateP = Pattern.compile("Дата подачи:\\s*(.+)");        private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy");        public static void main(String[] args) {                ExecutorService executor = Executors.newFixedThreadPool(100);                while (true) {                        executor.submit(new Runnable() {                                @Override                                public void run() {                                        workConcurrently();                                }                        });                }        }        public static void workConcurrently() {                Matcher matcher = dateCreateP.matcher("Дата подачи: 19:30:55 03.05.2015");                Timestamp startAdvDate = null;                try {                        if (matcher.find()) {                                String dateCreate = matcher.group(1);                                startAdvDate = new Timestamp(sdf.parse(dateCreate).getTime());                        }                } catch (Throwable th) {                        th.printStackTrace();                }                System.out.print("OK ");        }}

And result :

OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK OK java.lang.NumberFormatException: For input string: ".201519E.2015192E2"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:2056)at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)at java.text.DateFormat.parse(DateFormat.java:364)at com.nonscalper.webscraper.processor.av.ExampleClass.workConcurrently(ExampleClass.java:37)at com.nonscalper.webscraper.processor.av.ExampleClass$1.run(ExampleClass.java:25)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)

解决方案

  1. 每次 new (实例化) SimpleDateFormat

  2. 利用 ThreadLocal 确保每个线程都可以得到单独的一个 SimpleDateFormat

public class DateUtil {        private static final ThreadLocal local = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));        public static String format(Date date) {                return local.get().format(date);        }        public static Date parse(String dateStr) throws ParseException {                return local.get().parse(dateStr);        }}
  1. commons-lang3 中的 FastDateFormat

    org.apache.commons    commons-lang3    ${commons-lang3-version}

性能比拼

性能咋样,jmh 来一把,源码见:https://github.com/lets-mica/mica-jmh

# JMH version: 1.21# VM version: JDK 1.8.0_221, Java HotSpot(TM) 64-Bit Server VM, 25.221-b11Benchmark             Mode  Cnt       Score       Error  UnitsnewSimpleDateFormat  thrpt    5  114072.841 ±   989.135  ops/sthreadLocal          thrpt    5  348207.331 ± 46014.175  ops/sfastDateFormat       thrpt    5  434391.553 ±  7799.593  ops/s

结果:fastDateFormat 得分最高。当然你觉得这样就完了?

利用 Instant + DateTimeFormatter

mica 1.2.1 中我们利用 Instant 来中转 Date 使用 DateTimeFormatter 格式化。

public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());public String format(Date date) {        return DATETIME_FORMATTER.format(date.toInstant());}

注意:DateTimeFormatter 格式化 Instant 需要指定时区

jdk 8 压测结果

# JMH version: 1.21# VM version: JDK 1.8.0_221, Java HotSpot(TM) 64-Bit Server VM, 25.221-b11Benchmark         Mode  Cnt       Score      Error  UnitsfastDateFormat   thrpt    5  417338.980  56543.104  ops/stoInstantFormat  thrpt    5  371028.709  72059.917  ops/s

jdk 11 压测结果

# JMH version: 1.21# VM version: JDK 11.0.4, OpenJDK 64-Bit Server VM, 11.0.4+10-b304.69Benchmark         Mode  Cnt       Score      Error  UnitsfastDateFormat   thrpt    5  384637.138   7402.690  ops/stoInstantFormat  thrpt    5  487482.436  12490.986  ops/s

感谢各位的阅读,以上就是"如何使用java8的格式化Date"的内容了,经过本文的学习后,相信大家对如何使用java8的格式化Date这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0