2010-11-22 20 views
2

私はJavaスレッドの動作を理解するのに苦労しています。Javaスレッド - スレッドのローカル変数

N個のスレッドを持つプログラムがあるとします。各スレッドは、文字列の配列の異なる部分で同じ命令を実行します。実行可能なインタフェースを持つクラスを通してスレッドを呼び出します。この例の目的のために、それはこのようなものであるとしましょう:

run() { 
    while (startStop = loopGetRange() != null) { 

     countLetters(startStop.start,startStop.stop); 
     /* start is the beginning cell in the array where the process starts 
      and stop is the ending cell in the array where the process stops */ 
    } 
} 

最後countLettersは、次のように単純な方法である:

private void countLeters (int start, int stop) { 
    for (int y = start; <= stop; y++) { 
     String theWord = globalArray[y]; 
     int z = theWord.length; 
     System.out.println("For word "+theWord+" there are "+z+" characters"); 
    } 
} 

ここに私の質問です:「theWord」のような変数であります「Z」はスレッドにローカルであるか、またはスレッド全体で共有されているため、スレッドが衝突する可能性があります。後者の場合、これらの変数をどのように保護するのが最善か。

困ったことに助けてくれてありがとう。

エリオット

答えて

7

ローカル変数はスタックに割り当てられ、スレッドに対してローカルです。メンバフィールドのみがスレッド間で共有されます。したがって、theWordZはスレッド間で共有されないため、クラッシュを心配する必要はありません。

文字列が不変であることを考えると、countLeters()メソッドでスレッドセーフティについて懸念するのは、globalArrayへのアクセスだけです。

ここで、この配列の構築がglobalArrayへのアクセスの前に起こった場合、スレッドはglobalArrayに「書き込み」しない限り、コードは安全です。

「起こっ-前に」の関係は(java.util.concurrentライブラリなどを使用して、​​キーワード、finalキーワード、volatileキーワードを使用して)いくつかの方法により実施することができます。

+0

これは非常に明確です。ご説明をいただき、ありがとうございます。 – Elliott

1

このスレッドは、どの変数が表示されるかには影響しません。クラスを作成してスレッドを開始せずにメソッドを実行したようなものです。複数のスレッドが同じオブジェクトにアクセスする場合は、ロックを使用して互いを踏まないようにしなければなりません。

+0

スレッドローカル変数は、スレッドを処理するスレッドがあれば、スレッドごとに追跡できます。静的変数はこの実行可能ファイルのすべてのインスタンスで共有されます。 –

+0

はい、ThreadLocalがありますが、彼がここで求めているようには見えません。 – JOTN

0

JOTNと同様に、スレッドが同じオブジェクトにアクセスしている場合、スレッドの衝突が発生する可能性があります。それ又はその要素がを変更された場合

この場合 globalArray変数はスレッド間で共有されている場合

、及び特に、ロック/同期を使用するのが賢明かもしれません。共有変数の変数とロック/同期の問題の可視性とは別に

+0

OK。グローバル配列は変更されていません。私はcountLettersメソッドの変数についてもっと気にしています。実行中に呼び出されるメソッドです。私が正しく理解していれば、countLettersメソッドのローカル変数が結論の対象となるように見えるでしょう。これは正しいです?その場合、メソッドとしてcountLettersを呼び出すのではなく、Counting lettersというクラスを作成し、ラップされたメソッドをintantiationの一部として呼び出すと、問題を回避できますか? – Elliott

+0

私はあなたが「結論に従う」ことを意味するかどうかは確かではありません。しかし、メソッド内で作成される変数は、メソッドにとってローカルです。しかし、書いた例では 'String theWord = globalArray [y];'を実行します。ここでtheWordは 'gloablArray [y]'のオブジェクトへの参照になります。私はクラスでこれをラップすると違いが出るのかどうかはわかりません。 –

0

...

は、あなたが求めるこれらの変数スレッド

にローカル「theWord」と「Z」のような変数ですループのローカルであり、クラスやインスタンスの一部ではなく、スレッドごとに存在するため、衝突はありません。

関連する問題