1

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

私の質問はlineCntreadNWrite()メソッド内をスレッドローカルにする必要がありますか?

4

4 に答える 4

2

lineCntスタック上にあるため、すでに「スレッドローカル」です。ThreadLocalインスタンスメンバー変数のスレッドローカルコピーが必要な場合にのみ使用してください。

于 2013-01-03T06:13:11.850 に答える
2

いいえ、ここでThreadLocalを使用する必要はありません-コードは完全に正常に見えます:

  • lineCntはローカル変数であるため、スレッド間で共有されません=>スレッドセーフです
  • counter.getAndAdd(lineCnt);アトミックでスレッドセーフな操作です

興味がある場合は、このようなThreadLocalの使用に関するSOに関するいくつかの投稿があります。

于 2013-01-03T06:13:20.173 に答える
1

lineCntをThreadLocal明示的にする必要はありません。lineCntスレッドのローカル変数です。他のスレッドからはアクセスできません。

ThreadLocalの詳細については、こちらをご覧ください。

javadocのThreadLocal

これらの変数は、(getまたはsetメソッドを介して)1つにアクセスする各スレッドが、変数の独自の独立して初期化されたコピーを持っているという点で、通常の対応する変数とは異なります。ThreadLocalインスタンスは通常、状態をスレッドに関連付けたいクラスのプライベート静的フィールドです。

于 2013-01-03T06:18:20.997 に答える
1

-AThreadは、、、およびがあります。StackRegisterProgram Counter

- lineCntはすでにになっていThreadLocalます。

- lineCntは、このスレッドのインスタンス変数lineCntの個人用コピーであり、他のスレッドには表示されません。

于 2013-01-03T06:22:08.407 に答える