2012-07-18 13 views
18

可変スコープに関する質問があります。例えば静的メソッドとスレッドセーフティのローカル変数

class A { 
    private static void test() { 
     // do something with local variables 
    } 
} 

は今、私は2つのスレッドを作成し、各スレッドのためにAの1つのインスタンスを作成します。

  1. 私は、各スレッドでtest()を呼んで、私はtest()は、スレッドセーフであることを保証することができますか?

  2. test()のローカル変数はどこに保存されていますか?各スレッドのスタック?ヒープスペース?

P.S.この場合、静的は完全に無意味だと私は知っています。私はレガシーコードでそれを見つけました。私はただ私が知っていることを確認したい!

答えて

28

ローカル変数は、各スレッド独自のスタックに格納されます。つまり、ローカル変数は決してスレッド間で共有されません。つまり、すべてのローカルプリミティブ変数はスレッドセーフです。

オブジェクトへのローカル参照は少し異なります。参照自体は共有されていません。ただし、参照されるオブジェクトは、各スレッドのローカルスタックに格納されません。すべてのオブジェクトは共有ヒープに格納されます。ローカルで作成されたオブジェクトが作成されたメソッドをエスケープしない場合は、スレッドセーフです。実際には、これらのメソッドやオブジェクトのどれも渡されたオブジェクトを他のスレッドが利用できるようにしない限り、他のメソッドやオブジェクトに渡すこともできます。

オブジェクトメンバーは、オブジェクトと共にヒープに格納されます。したがって、2つのスレッドが同じオブジェクトインスタンス上のメソッドを呼び出し、このメソッドがオブジェクトメンバを更新する場合、このメソッドはスレッドセーフではありません。

スレッドセーフティチェック:リソースが作成され、使用され、同じスレッドの制御内に配置され、このスレッドの制御をエスケープしない場合、そのリソースの使用はスレッドセーフです。

http://tutorials.jenkov.com/java-concurrency/thread-safety.html

+2

+1、あなたは確かに「合格」、(信号)することができますがが、他のスレッドに上のオブジェクトが、それは通常、例えば、それの「所有権を放棄」する必要があり作成されたスレッド。それ自身の参照をnullにするか、別のオブジェクトを作成して上書きして、2つのスレッドが同じオブジェクトに対して決して動作しないようにします。これが行われないと、オブジェクトは説明どおりに共有され、アクセスのためにロックが必要になります。 –

+0

はい、その理由から、参照をnullにすることによってオブジェクトを破棄することは良い考えです。 – Erol

+0

偉大な私はこの質問をしようとしていた!!!! – JohnMerlino

0

番号1については、私はtest()が何をするのか分からないので、私は答えることができません。クラスAの変数staticを変更すると、スレッドセーフではない可能性があります。途中の両方のスレッドが同じオブジェクトへの参照を与えられている場合、オブジェクトの定義方法によってはスレッドセーフではない可能性があります。

番号2の場合、ローカル変数は各スレッドのスタックにあります(または少なくとも概念的にはそうです)。したがって、ローカル変数が他のスレッドによって変更される心配はありません。

2

各スレッドでtest()を呼び出すと、test()がスレッドセーフであることを保証できますか?

はい、test()メソッドではメソッドローカル変数 を処理しているとスレッドセーフになります。

test()のローカル変数はどこに保存されていますか?各スレッドのスタック?ヒープスペース?

メソッドローカル変数は、各スレッド独自のスタックに格納されます。

関連する問題