import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
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 t = sdf.parse("2015-03-29 19:29:"+i%60);
System.out.println(i + ":" + t);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService es=Executors.newFixedThreadPool(10);
//通过线程执行不同的Runnable,但是Runnable使用的是同一个SimpleDateFormat
for(int i = 0;i < 1000;i++){
es.execute(new ParseDate(i));
}
es.shutdown();
}
}
如果你发现了问题,是不是考虑到了SimpleDateFormat 类的parse()方法不是线程安全的,所以程序运行过程中,可能会报错。
或许你会想到在parse方法前后加锁,这也是一种可行的方法。今天我们来学习使用新的技能ThreadLocal。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
static ThreadLocal<SimpleDateFormat> t1 = new ThreadLocal<SimpleDateFormat>();
public static class ParseDate implements Runnable {
int i = 0;
public ParseDate(int i) {
this.i = i;
}
@Override
public void run() {
try {
// 如果当前线程没有SimpleDateFormat实例,则为当前线程创建。否则,直接获取。
if (t1.get() == null) {
t1.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}
Date t = t1.get().parse("2015-03-29 19:29:" + i % 60);
System.out.println(i + ":" + t);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(10);
// 通过线程执行不同的Runnable,但是Runnable使用的是同一个SimpleDateFormat
for (int i = 0; i < 1000; i++) {
es.execute(new ParseDate(i));
}
es.shutdown();
}
}
转载出处:http://www.jianshu.com/p/bcdd8efe5070