12月2日(水)1コマ目
今日、やったこと
Javaのスレッドと各変数
前回は
サンプルプログラム「ThreadTest1.java」を使って、
各スレッド間でクラスメソッド内のローカル変数は共有しないか?
を確認しました。
結論から
ローカル変数はメソッド呼び出し時にスタックエリア上にエリアが確保される。
このスタックエリア上に確保されたエリアはメソッド終了時に開放される。
です。よって、クラスメソッドだろうが、インスタンスメソッドだろうがメソッド内で宣言したローカル変数はマルチスレッド環境でもスレッド間で共有することはないです。
|
|
図 1インスタンス=>2スレッド、クラスメソッド内のローカル変数は共有する? |
今日のホワイトボード
スレッド間でフィールドは共有する?①
サンプルプログラム「ThreadTest2.java」で確認です。
実行するとフィールドinsSumはスレッド間で共有されていることがよくわかりました。
このプログラムのフィールドとスレッドの関係は図のとおりで、同じインスタンスから生成されたスレッド同士ではフィールドを共有します。
|
|
図 1インスタンス=>2スレッド、フィールドは共有する? |
このような場合は、スレッド間でフィールドの上書き問題が発生します。通常のフィールドと同じ感覚で使うと危険です。
スレッド間でフィールドは共有する?②
サンプルプログラム「ThreadTest2_5.java」で確認です。ぱっと見「ThreadTest2.java」に似ています。
しかし、実行するとフィールドinsSumはスレッド間で共有されていません。
プログラムをよく見ると、main()ないでインスタンスを2つ生成し、各インスタンスからスレッドを起動しています。
結局、スレッドが参照するインスタンスは別々になるため、フィールドを共有することはありません。
|
|
図 2インスタンス=>2スレッド、フィールドは共有する? |
スレッド間でクラス変数は共有する?①
サンプルプログラム「ThreadTest3.java」で確認です。
このプログラムでは、フィールドのかわりにクラス変数を使っています。
実行すると、このクラス変数はスレッド間で共有されています。
クラス変数はクラスで1つだけです。スレッドうんぬんではなく、インスタンス間でも共有します。
|
|
図 1インスタンス=>2スレッド、スレッド間でクラス変数は共有する? |
スレッド間でクラス変数は共有する?②
サンプルプログラム「ThreadTest3_5.java」で確認です。
このプログラムは「ThreadTest3.java」からmain()内でインスタンスを2つ生成し、各インスタンスからスレッドを起動しています。
結局、クラス変数はクラスで1つだけです。実行するとやはり共有しています。
|
|
図 2インスタンス=>2スレッド、スレッド間でクラス変数は共有する? |
まとめ
意識してほしいのは「各変数がいつ、どこにエリアが確保され、いつ解放されるか」です。
| 変数の種類 | いつエリアが確保される | どこにエリアが確保される | エリアはいつ解放される |
|---|---|---|---|
| ローカル変数 | メソッド呼び出し時 | スタックエリア | メソッド終了時 |
| インスタンス変数 (フィールド) |
インスタンス生成時 | ヒープエリア | ガーベージコレクションでインスタンスが削除されるとき |
| クラス変数 | クラスロード時 | メソッドエリア | クラスが破棄されるとき |
なにごともなければ次回紙のテストです。





コメント