Javaマルチスレッドプログラミング-スレッドを使用する欠点


1、初期起動が遅くなる
    一部のプラットフォームでは、新しいスレッドの作成と起動が比較的遅いため、パフォーマンスが最も優れているアプリケーションでは大きな欠点になる可能性があります.しかし、スレッド・プール・テクノロジーは、このような問題の簡単な解決策を提供し、多くの同時操作を実行するアプリケーションは、通常、スレッド・プールを使用します.特に、アプリケーション・オペレーションの完了速度が速い場合、スレッド・プールを使用するのに適しています.スレッド・プールの概念は、データベース接続プールに似ています.
2、資源利用
    各スレッドには、変数値やその他の実行情報を含むストレージ領域である独自のスタックを割り当てる必要があります.スタックに加えて、スレッドは他のシステムリソースを使用しますが、JVMで使用されるリソースの数とタイプによって異なります.大量のスレッドを作成する必要がある場合がありますが、使用するプラットフォームでは、スレッドの作成数が制限される場合があります.すべてのプラットフォームで作成できるスレッドの数が明示的に制限されていない場合でも、プロセッサの速度やシステムで使用可能なメモリによっては一般的に制限されます.
    この問題は解消できないが,スレッドプール技術により制御できる.スレッドプールを使用すると、新しいスレッドの作成にかかるシステムオーバーヘッドを排除できるほか、スレッドの作成数を減らすことができます.もちろん、アプリケーションがスレッドプールマネージャを使用して、スレッドの作成時刻とスレッドの作成数を制御できると仮定します.Javaではスレッドプールマネージャは実装されていません.
3、複雑性の増加
    アプリケーションでスレッドを使用する最大の欠点は、複雑さを増大させることです.たとえば、単一スレッドアプリケーションをデバッグするときにアプリケーションの実行プロセスを簡単に観察できますが、マルチスレッドアプリケーションでは実行プロセスを観察するのは難しいです.
    スレッドのセキュリティは、オブジェクト設計にも関係します.スレッドは、オブジェクトデータを変更すると、別のオブジェクトがデータを読み書きできません.ここでのデータとは、オブジェクトにカプセル化された情報を指し、1つのデータ項目がオブジェクトの1つ以上のフィールドで構成される可能性がある.
    もう1つのより複雑な問題は、複数のスレッド間のリソース共有です.ここでのリソースとは、複数のスレッドで同時にアクセスできる任意のエンティティを指し、ほとんどの場合、スレッドのリソース使用のプロビジョニングを担当する必要があります.たとえば、さまざまなSwingコンポーネント自体がスレッドセキュリティではない場合は、アプリケーションのスレッドとAWTイベントスレッドのSwingコンポーネントの使用方法を考慮します.通常、SwingUtilitiesクラスのinvokeAndWait()メソッドとinvokeLate()メソッドを使用して、可視コンポーネントの変更をAWTイベントスレッドに委任します.
リソース共有の定義
    このメソッドで定義されたローカル変数はメソッドの外にアクセスできないため、複数のスレッドが同じオブジェクトのメソッドを実行するときに変数を共有できません.たとえば、2つのスレッドを作成して同じRunnableオブジェクトインスタンスを使用するアプリケーションを実行するとします.
 1 public class ThreadShare  implements Runnable{

 2  

 3     public static void main(String[] args){

 4         ThreadShare ts = new ThreadShare();

 5         Thread t1 = new Thread(ts);

 6         Thread t2 = new Thread(ts);

 7         t1.start();

 8         t2.start();

 9     }

10     public void run(){

11         int nonSharedValue = 100;

12         nonSharedValue += 100;

13         System.out.println("value:" + nonSharedValue);

14     }

15 }

    nonSharedValue変数はrun()メソッドで定義されるため、メソッドのローカル変数であり、2つのスレッドで共有できません.スレッドごとにnonSharedValueのコピーが作成され、アプリケーションを実行して次のように出力されます.
     value: 200
     value: 200
    ただし、アプリケーションを変更してrun()メソッドにインスタンス変数を追加すると、この変数は共有リソースになります.
 1 public class ThreadShare  implements Runnable{

 2  

 3     int nonSharedValue = 100;

 4     public static void main(String[] args){

 5         ThreadShare ts = new ThreadShare();

 6         Thread t1 = new Thread(ts);

 7         Thread t2 = new Thread(ts);

 8         t1.start();

 9         t2.start();

10     }

11     public void run(){

12         

13         nonSharedValue += 100;

14         System.out.println("value:" + nonSharedValue);

15     }

16 }