ThreadLocal initialValue()每个线程多次调用。为什么?

时间:2014-04-17 21:31:51

标签: java thread-local

由于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。

为什么每个线程多次调用它?

2 个答案:

答案 0 :(得分:1)

这看起来像是在多个线程中使用相同的Timer对象。您应该将new Timer()移至initialValue()。只有这样,您才能确保每个线程都有一个唯一的Timer对象。从您的代码中猜测,config是不可变的,因此您可以将this传递给计时器。然后,您只需创建一个MonMetrics并在所有线程中重复使用它。

答案 1 :(得分:0)

看起来java thread本地不保证initialValue()只会被调用一次! 所以最好假设它可以被调用任意次。