map取不到值的一次踩坑(慎用Date的toString方法)
问题描述
见如下代码,若map的key使用了date,可能造成第17行从map中取不到值
问题分析
map做put是调用了purchaseDate的toString()方法,而toString()方法中调用normalize(),normalize()中有获取默认时区的操作。如果map的put动作之后,get之前有其他线程修改掉了defaultTimeZone,由于defaultTimeZone为volatile关键字修饰,会使得17行get方法中的值改变,导致17行获取到null。
补充:volatile关键字 被用来保证可见性,即保证共享变量的内存可见性以解决缓存一致性问题。一旦一个共享变量被 volatile关键字 修饰,那么就具备了两层语义:内存可见性和禁止进行指令重排序。在多线程环境下,volatile关键字 主要用于及时感知共享变量的修改,并使得其他线程可以立即得到变量的最新值,例如,用于 修饰状态标记量 和 Double-Check (双重检查)中。
问题解决
将日期转为long使用时间戳。