ThreadLocal 线程局部变量 所以只能当前线程可以访问 即线程安全
下面看简单示例
public class ParseDateDemo {
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static class ParseDate implements Runnable {
int i = 0;
public ParseDate(int i) {
this.i = i;
}
@Override
public void run() {
try {
Date date = sdf.parse("2018-12-05 09:33:" + i % 60);
System.out.println(i + ":" + date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
executorService.execute(new ParseDate(i));
}
}
}
执行结果
Exception in thread "pool-1-thread-8" java.lang.NumberFormatException: multiple points
Exception in thread "pool-1-thread-3" java.lang.NumberFormatException: For input string: ""
异常原因:因为SimpleDateFormat不是线程安全的 在线程池中共享此对象必然导致错误!!
下面是给SimpleDateFormat加上ThreadLocal后 代码示例
public class ParseDateDemo {
//private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
public static class ParseDate implements Runnable {
int i = 0;
public ParseDate(int i) {
this.i = i;
}
@Override
public void run() {
try {
if(tl.get()==null) {
tl.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}
Date date = tl.get().parse("2018-12-05 09:33:" + i % 60);
System.out.println(i + ":" + date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
executorService.execute(new ParseDate(i));
}
}
}
需要特别注意:ThreadLocal只是为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享,并且为每个线程分配一个对象并不是ThreadLocal操作 而是应用层操作