2013-01-03 85 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 個人副本這個線程,其不可見任何其他線程。