SimpleDateFormat為非線程(Thread)安全, 多線程時會造成問題。
方法一:
直接用static
缺點:不同線程的安全性(皆能共享)
方法二:
使用時才new一個
缺點:消耗內存, 影響效能
方法三:
最推薦的方式為透過ThreadLocal
ThreadLocal可根據不同線程, 存取不同的值,
舉個例子:
final int num = 10;
final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(num);
Log.e("adam", "test, 1, get: " + threadLocal.get());
new Thread(new Runnable() {
@Override
public void run() {
threadLocal.set(20);
Log.e("adam", "test, 2, get: " + threadLocal.get());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
Log.e("adam", "test, 3, get: " + threadLocal.get());
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("adam", "test, 4, get: " + threadLocal.get());
}
});
}
}).start();
結果:
test, 1, get: 10
test, 2, get: 20
test, 3, get: null
test, 4, get: 10
Thread中沒設值時, 取出的是null, UIThreadhread設的是10, 並沒有因為第一個Thread設值20而改變, test 4依然是10。
由此可確認,ThreadLocal的存取是獨立於不同線程。
SimpleDateFormat透過ThreadLocal:
private static final ThreadLocal<DateFormat> dateFormatThreadLocal = new ThreadLocal<DateFormat>();
private static DateFormat getDateFormat(String format){
DateFormat dateFormat = dateFormatThreadLocal.get();
if(dateFormat == null){
dateFormat = new SimpleDateFormat(format);
dateFormatThreadLocal.set(dateFormat);
}
return dateFormat;
}