日期格式不是同步的,建议为每个线程创建独立的格式实例,如果同时访问一个格式,则他必须保持外部同步.
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; public class Constants { private static final ThreadLocal<DateFormat> DF = new ThreadLocal<DateFormat>() { protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; public static void main(String[] args) throws ParseException{ DF.get().parse("2014-09-01"); } }
DF一般会被写在常量类中,但使用Sonar的findbug功能可以诊断出应该用ThreadLocal去保证线程安全.
ThreadLoal更准确的表述应该叫ThreadLocalVariable(线程局部变量),它为每个使用该变量的线程提供一个该变量的副本.
从线程的角度看,每个线程都保持一个句柄指向变量的副本,知道线程结束,该变量副本被GC回收,此处存在一个线程绑定机制。
因此对于多线程共享同一个资源的问题,同步机制是"以时间换空间",而ThreadLocal是"空间换时间",用于数据隔离.