由于ThreadLocal的initialValue()被多次调用,我们发现了一个问题。
private static class MonMetricsTLS extends ThreadLocal<IMonitor> {
public MonMetricsTLS(MetricConfig config) {
this.config = config;
Timer timer = new Timer(true);
}
@Override
protected IMonitor initialValue() {
IMonitor mon = new MonitorImpl(config);
timer.schedule(new SenderTimerTask(mon), config.senderPeriodMs(), config.senderPeriodMs());
return mon;
}
}
在第一次和第二次调用之间,计时器可能会变坏,我们在schedule()中会遇到illegalstateexception。
为什么每个线程多次调用它?
答案 0 :(得分:1)
这看起来像是在多个线程中使用相同的Timer
对象。您应该将new Timer()
移至initialValue()
。只有这样,您才能确保每个线程都有一个唯一的Timer
对象。从您的代码中猜测,config
是不可变的,因此您可以将this
传递给计时器。然后,您只需创建一个MonMetrics并在所有线程中重复使用它。
答案 1 :(得分:0)
看起来java thread本地不保证initialValue()只会被调用一次! 所以最好假设它可以被调用任意次。