2013-01-03 86 views
1

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

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); 
    } 
} 

我的问题是,我需要做的lineCntreadNWrite()方法是ThreadLocal的?

回答

2

不,你不需要在这里使用ThreadLocal的 - 你的代码看起来完美的罚款:

  • lineCnt是因此不能跨线程共享一个局部变量=>它是线程安全的
  • counter.getAndAdd(lineCnt);被一个原子和线程安全操作

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

2

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

1

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

您可以从javadoc

这些变量从正常的同行不同,获取的ThreadLocal更多信息here

ThreadLocal中,每个 线程访问(通过其get或set方法)一个有自己, 变量的独立初始化副本。 ThreadLocal的情况下 通常是类中的私有静态字段,它们希望以 状态线程

1

关联 -一个ThreadStackRegisterProgram Counter

-lineCnt已经进入ThreadLocal

-lineCnt是实例变量LINECNT 个人副本这个线程,其不可见任何其他线程。