ThreadLocal需要在这里使用吗?

时间:2013-01-03 06:10:38

标签: java multithreading thread-local

我想知道我们什么时候需要使用threadlocal变量?我有一个运行多个线程的代码,每个都读取S3上的一些文件,我希望跟踪从文件中读出多少行,这是我的代码:

final AtomicInteger logLineCounter = new AtomicInteger(0); 
for(File f : files) {
   calls.add(_exec.submit(new Callable<Void>() {
    @Override
    public Void call() throws Exception {
       readNWrite(f, logLineCounter);
       return null;
    }
    }));
}
for (Future<Void> f : calls) {
   try {
      f.get();
   } catch (Exception e) {
      //
   }
}
LOGGER.info("Total number of lines: " + logLineCounter);
...

private void readNWrite(File f, AtomicInteger counter) {
    Iterator<Activity> it = _dataReader.read(file);

    int lineCnt = 0;
    if (it != null && it.hasNext()) {
       while(it.hasNext()) {
         lineCnt++;
         // write to temp file here

       }
       counter.getAndAdd(lineCnt);
    }
}

我的问题是,我是否需要将lineCnt方法中的readNWrite()设为threadlocal?

4 个答案:

答案 0 :(得分:2)

lineCnt已经是“线程本地”,因为它在堆栈上。仅在需要实例成员变量的线程局部副本时才使用ThreadLocal

答案 1 :(得分:2)

不,你不需要在这里使用ThreadLocal - 你的代码看起来非常好:

  • lineCnt是一个局部变量,因此不会在thread =&gt;中共享它是线程安全的
  • counter.getAndAdd(lineCnt);是原子和线程安全的操作

如果您有兴趣,有关于ThreadLocal使用的SO有几篇帖子,例如this one

答案 2 :(得分:1)

您不需要明确地将lineCnt设为ThreadLocallineCnt是线程的局部变量。任何其他线程都无法访问它。

您可以获得有关ThreadLocal here

的更多信息

来自javadoc

的ThreadLocal
  

这些变量与正常对应物的不同之处在于每个变量   访问一个(通过其get或set方法)的线程有自己的,   独立初始化变量的副本。 ThreadLocal实例   通常是希望关联的类中的私有静态字段   状态与线程

答案 3 :(得分:1)

- ThreadStackRegisterProgram Counter

- lineCnt已进入ThreadLocal

- lineCnt是此主题的实例变量lineCnt 个人副本,其不可见到任何其他线程。