Java8中的线程安全日期类怎么使用


本篇内容主要讲解“Java8中的线程安全日期类怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java8中的线程安全日期类怎么使用”吧!Java8新特性之一,新增日期类。在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】Java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改可以使用Instant代替 Date,LocalDateTime代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat。Date如果不格式化,打印出的日期可读性差使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的 SimpleDateFormat的format方法最终调用源码:注意calendar.setTime(date);,Calendar类是里面基本都是final修饰的,calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat,一般会封装在工具类,复用】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。在多并发情况下使用SimpleDateFormat需格外注意:SimpleDateFormat除了format方法是线程不安全以外,parse方法也是线程不安全的。parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了重置日期对象cal的属性值使用calb(calBuilder)中属性设置cal返回设置好的cal对象但是这三步不是原子操作避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大对使用format和parse方法的地方进行加锁 => 线程阻塞性能差使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理的话真是太难了,你可能会说Date类不是有getYear、getMonth这些方法吗,获取年月日很Easy,但都被弃用了啊在使用Java程序操作数据库时,我们需要把数据库类型与Java类型映射起来。下表是数据库类型与Java新旧API的映射关系:只会获取年月日只会获取几点几分几秒获取年月日时分秒,等于LocalDate+LocalTimeLocalDateTime总是表示本地日期和时间,要表示一个带时区的日期和时间,我们就需要ZonedDateTime。可以简单地把ZonedDateTime理解成LocalDateTimeZoneIdZoneIdjava.time引入的新的时区类,注意和旧的java.util.TimeZone区别。创建一个ZonedDateTime对象结果:2019-09-15T20:58:18.786182+08:00[Asia/Shanghai]
2019-09-15T08:58:18.788860-04:00[America/New_York]另一种创建方式是通过给一个LocalDateTime附加一个ZoneId,就可以变成ZonedDateTime时区转换要转换时区,首先我们需要有一个ZonedDateTime对象,然后,通过withZoneSameInstant()将关联时区转换到另一免费云主机域名个时区,转换后日期和时间都会相应调整。ZonedDateTime仍然提供了plusDays()等加减操作。要特别注意,时区转换的时候,由于夏令时的存在,不同的日期转换的结果很可能是不同的。这是北京时间9月15日的转换结果:2019-09-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-09-15T09:05:50.187697-04:00[America/New_York]这是北京时间11月15日的转换结果:2019-11-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-11-15T08:05:50.187697-05:00[America/New_York]两次转换后的纽约时间有1小时的夏令时时差。涉及到时区时,千万不要自己计算时差,否则难以正确处理夏令时。有了ZonedDateTime,将其转换为本地时间就非常简单:转换为LocalDateTime时,直接丢弃了时区信息。获取秒数或时间戳System.currentTimeMillis()也可以获取毫秒数。LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本增加、减少年数、月数、天数等,以LocalDateTime为例有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案比如通过firstDayOfYear()返回了当前年的第一天日期,还有很多方法这里不在举例说明DateTimeFormatter默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过DateTimeFormatter的ofPattern方法创建自定义格式化方式和SimpleDateFormat相比,DateTimeFormatter是线程安全的使用旧的Date对象时,我们用SimpleDateFormat进行格式化显示。使用新的LocalDateTimeZonedLocalDateTime时,我们要进行格式化显示,就要使用DateTimeFormatter。和SimpleDateFormat不同的是,DateTimeFormatter不但是不变对象,它还是线程安全的。因为SimpleDateFormat不是线程安全的,使用的时候,只能在方法内部创建新的局部变量。而DateTimeFormatter可以只创建一个实例,到处引用。DateTimeFormatter线程安全的?为什么?很明显,通过final修饰类,不可被继承,final修饰变量,做成了不可变类,类似String,不仅线程安全而且高效。全局可以只有一个对象,多个线程引用。使用LocalDateTime的format和parse方法,传入对应的DateTimeFormatter对象参数,实际也是调用DateTimeFormatter的format和parse方法,实现日期格式化和解析,是线程安全的。DateTimeFormatter类解析LocalDateTime中的日期变量,转成StringBuilder返回。LocalDateTime等新出的日期类全是final修饰的类,不能被继承,且对应的日期变量都是final修饰的,也就是不可变类。赋值一次后就不可变,不存在多线程数据问题。到此,相信大家对“Java8中的线程安全日期类怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是百云主机网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

相关推荐: Java的Lombok如何安装与使用

这篇文章主要介绍了Java的Lombok如何安装与使用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Lombok的安装分两部分:Idea插件的安装和maven中pom文件的导入。点击设置,选择插…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 09/08 17:07
下一篇 09/08 17:07

相关推荐