ThreadLocal 提供 3 個 public method 與 1 個 protected method
T get() protected T initialValue() void remove() void set(T value)ThreadLocal 內部儲存值的方式, 其實是利用到 thread 實例中的 threadLocals 實例變數(instance variable),threadLocals 是個類似於 HashMap 的物件, ThreadLocal 將自身實例當作 key, 將 set 的值設定到 threadLocals 物件參考中
ThreadLocal set method source code
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t);//reference to t.threadLocals if (map != null) map.set(this, value); else createMap(t, value);//t.threadLocals = new ThreadLocalMap(this, value); }ThreadLocal set 的資料實際上是儲存於 thread instance 中, 這樣做的好處是當該 thread instance 被 GC 後 ThreadLocal 儲存的參考也跟著消失了,不會有記憶體洩漏(memory leak)的問題
ThreadLocal example:
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TestThreadLocal {
private final static ThreadLocal<Date> endDate = new ThreadLocal<Date>() {
@Override
protected Date initialValue() {
return new Date();
}
};
public static void main(String[] args) {
final ExecutorService exec = Executors.newCachedThreadPool();
final Runnable task = () -> { //Java lambda expression
try {
TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
} catch (final InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread Completed: %1$d : %2$tF %2$tT%n", Thread
.currentThread().getId(), TestThreadLocal.endDate.get());
};
for (int i = 0; i < 10; i++) {
exec.execute(task);
}
exec.shutdown();
}
}
0 comments:
Post a Comment