「こんにちは、アミーゴ! 昨日はマルチスレッドの利点と利便性について話し合いました。今度は欠点を見てみましょう。残念ながら、それらは小さくありません。」
以前は、プログラムを、相互にメソッドを呼び出し合うオブジェクトのセットとして見てきました。ここで、すべてが少し複雑になります。プログラムは、複数の「小さなロボット」(スレッド) が内部を巡回し、メソッドに含まれるコマンドを実行するオブジェクトのセットに似ています。
この新しい解釈は最初の解釈を取り消すものではありません。これらは依然としてオブジェクトであり、依然として互いのメソッドを呼び出します。ただし、複数のスレッドがあり、各スレッドが独自のジョブまたはタスクを実行することを覚えておく必要があります。
プログラムはますます複雑になっています。異なるスレッドは、実行するタスクに基づいて異なるオブジェクトの状態を変更します。そして、彼らはお互いのつま先を踏み合うことができます。
しかし、最悪の事態は Java マシンの奥深くで起こります。すでに述べたように、スレッドの見かけ上の同時性は、プロセッサが常に 1 つのスレッドから別のスレッドに切り替わることによって実現されます。スレッドに切り替えて 10 ミリ秒間動作し、次のスレッドに切り替えて 10 ミリ秒間動作する、というようになります。そしてここに問題があります。これらの切り替えは最も不都合な瞬間に発生する可能性があります。次の例を考えてみましょう。
最初のスレッドのコード | 2番目のスレッドのコード |
---|---|
|
|
表示されることを期待していたもの |
---|
ニックは15歳、 レナは21歳です。 |
実際のコードの実行 | 最初のスレッドのコード | 2番目のスレッドのコード |
---|---|---|
|
|
|
実際に表示されるもの |
---|
ニックは レナです 15 歳21 歳 |
別の例を次に示します。
コード | 説明 |
---|---|
|
変数と変数swap の値を交換するメソッドです。name1 name2
2 つのスレッドから同時に呼び出された場合はどうなるでしょうか? |
実際のコードの実行 | 最初のスレッドのコード | 2番目のスレッドのコード |
---|---|---|
|
|
|
結論 |
---|
両方の変数の値は«Lena»です。 «Ally» オブジェクトは成功しませんでした。紛失してしまいました。 |
「これほど単純な代入操作でこのようなエラーが発生する可能性があるとは誰が予想したでしょうか?!」
「はい、この問題には解決策があります。でも、これについては少し後で話します。喉が乾いています。」