JAVAスレッドの概要


スレッドとは?
ほとんどのオペレーティングシステムはプロセスの概念をサポートしています.プロセスはある程度互いに隔離され、独立して実行されるプログラムです.スレッド化は、複数のアクティビティが1つのプロセスに共存することを可能にするツールです.ほとんどの現代のオペレーティングシステムはスレッドをサポートしており、スレッドの概念は様々な形で長年存在しています.Javaは言語自体にスレッドを明示的に含む最初の主流のプログラミング言語であり、スレッド化を最下位のオペレーティングシステムのツールと見なしていない.スレッドは軽量レベルプロセスとも呼ばれる場合があります.プロセスのように、スレッドはプログラム内で独立した同時実行パスであり、各スレッドには独自のスタック、独自のプログラムカウンタ、および独自のローカル変数があります.ただし、プロセス内のスレッド間の分離は、分離されたプロセスに比べて小さくなります.メモリ、ファイルハンドル、および他の各プロセスのステータスを共有します.プロセスは、同時に実行されるように見えますが、互いに同期していない複数のスレッドをサポートします.1つのプロセス内の複数のスレッドは、同じメモリアドレス空間を共有します.これは、同じ変数とオブジェクトにアクセスし、同じスタックからオブジェクトを割り当てることができることを意味します.これにより、スレッド間で情報を共有することが容易になりますが、同じプロセス内の情報を妨げないように注意する必要がありますか?叱る?JavaスレッドツールとAPIは簡単に見えます.しかし,スレッドを有効に使用する複雑なプログラムの作成は容易ではない.複数のスレッドが同じメモリ領域に共有され、同じ変数が共有されているため、スレッドが互いに干渉しないように注意する必要があります.各Javaプログラムは、スレッドを使用します.各Javaプログラムには、少なくとも1つのスレッドであるプライマリスレッドがあります.Javaプログラムが起動すると、JVMはメインスレッドを作成し、そのスレッドでプログラムのmain()メソッドを呼び出します.JVMには他のスレッドも作成されています.通常、ゴミ収集、オブジェクトの終了、その他のJVM内務処理タスクに関連するスレッドなどは表示されません.他のツールもスレッドを作成し、AWT(Abstract Windowing Toolkit))やSwing UIツールボックス、servletコンテナ、アプリケーションサーバ、RMI(Remote Method Invocation)などです.スレッドの使用はなぜですか?Javaプログラムでスレッドを使用するのは多くの理由があります.Swing、servlet、RMI、Enterprise JavaBeansを使用する場合(EJB)テクノロジーは、すでにスレッドを使用していることに気づいていないかもしれません.スレッドを使用する理由のいくつかは、次のようなものです.
  • UI応答を高速化
  • マルチプロセッサシステム
  • を利用する
  • 簡略モデリング
  • 非同期またはバックグラウンド処理
  • を実行する.
    高速UI対応
    イベント駆動UIツールボックス(AWTやSwingなど)には、キーストロークやマウスクリックなどのUIイベントを処理するイベントスレッドがあります.AWTやSwingプログラムは、イベントリスナーをUIオブジェクトに接続します.特定のイベントの場合これらのリスナーは、ボタンをクリックした場合に通知されます.イベントリスナーはAWTイベントスレッドで呼び出されます.イベントリスナーが大きなドキュメントのスペルをチェックするなど、長い間タスクを実行する場合、スペルチェックを実行するためにイベントスレッドが忙しくなるため、イベントリスナーを完了するまで、追加のUIイベントを処理できません.プログラムが停滞しているように見え、ユーザーを困惑させます.UIの応答遅延を回避するには、イベントリスナーは、長いタスクを別のスレッドに配置する必要があります.これにより、AWTスレッドは、タスクの実行中にUIイベント(実行中の長時間タスクの実行をキャンセルする要求を含む)の処理を継続することができる.(MP)システムは以前よりも普及しています.以前は大規模なデータセンターや科学コンピューティング施設でしか見つからなかったのですが、現在では多くのローエンドサーバシステム、さらにはデスクトップシステムでも複数のプロセッサが存在しています.Linux、Solaris、Windows NT/2000など、現代のオペレーティングシステムでは、複数のプロセッサを利用してスレッドを任意の場所でスケジューリングできます理器で実行します.スケジューリングの基本単位は通常スレッドです.プログラムにアクティブなスレッドが1つしかない場合は、一度に1つのプロセッサでしか実行できません.プログラムに複数のアクティブなスレッドがある場合は、複数のスレッドを同時にスケジュールできます.丹念に設計されたプログラムでは、複数のスレッドを使用すると、プログラムのスループットとパフォーマンスが向上します.モデリングを簡略化する場合、スレッドを使用すると、プログラムの作成とメンテナンスがより簡単になります.複数のエンティティ間の相互作用をシミュレートするシミュレーションアプリケーションを考慮します.各エンティティに独自のスレッドを割り当てることで、多くのシミュレーションとアプリケーションのモデリングを大幅に簡素化できます.別のスレッドを使用してプログラムを簡略化するのに適した例は、1つのアプリケーションに複数の独立したイベント駆動コンポーネントがある場合です.たとえば、アプリケーションには、イベントの後に秒数でカウントダウンし、画面表示を更新するコンポーネントがある場合があります.1つのメインサイクルに定期的に時間をチェックして表示を更新させるよりも、1つのスレッドに何もしないで、ずっと休眠させて、?バリウム侥は奔浜P>リモート・ソースからのサーバ・アプリケーションの非同期またはバックグラウンド処理(ソケットのように)入力を取得します.ソケットを読み取る場合、現在使用可能なデータがない場合、SocketInputStream.read()の呼び出しは、使用可能なデータがあるまでブロックされます.単一スレッド・プログラムがソケットを読み取るのに、ソケットの反対側のエンティティがデータを送信していない場合、プログラムは他の処理を実行せずに永遠に待つだけです.逆に、プログラムは使用可能なデータがあるかどうかを確認するために、ソケットをポーリングしますが、パフォーマンスに影響を与えるため、通常は使用されません.ただし、ソケットを読み込むスレッドを作成した場合、このスレッドがソケットの入力を待つと、プライマリ・スレッドは他のタスクを実行できます.複数のスレッドを作成することもできます.これにより、複数のソケットを同時に読み込むことができます.これにより、使用可能なデータがある場合は、頻繁にポーリングして可否を確認する必要がなく、すぐに通知されます(待機中のスレッドが呼び出されているため).
    簡単ですが、リスクがある場合があります.
    Javaスレッドツールは使いやすいですが、マルチスレッドプログラムを作成するときは、リスクを最小限に抑える必要があります.複数のスレッドが同じデータ・アイテムにアクセスする場合(静的フィールド、グローバル・アクセス可能なオブジェクトのインスタンス・フィールド、または共有コレクションなど)では、データへのアクセスが調整されていることを確認する必要があります.これにより、データの一貫したビューが表示され、他方の変更に干渉しないようにする必要があります.この目的を達成するために、Java言語には、synchronizedvolatileの2つのキーワードが用意されています.このチュートリアルでは、後述します.で、これらのキーワードの用途と意義を研究します.複数のスレッドから変数にアクセスする場合は、そのアクセスが正しく同期されていることを確認する必要があります.単純な変数の場合、変数をvolatileと宣言すれば十分かもしれませんが、ほとんどの場合、同期を使用する必要があります.同期を使用して共有変数へのアクセスを保護する場合は、プログラム内のすべての変数にアクセスする場所で同期を使用する必要があります.スレッドは多くのタイプのアプリケーションを大幅に簡素化しますが、スレッドを過度に使用すると、プログラムのパフォーマンスとメンテナンス性を危険にさらす可能性があります.スレッドはリソースを消費します.したがって、パフォーマンスを低下させることなく作成できるスレッドの数には制限があります.特に、シングルプロセッサシステムでは、複数のスレッドを使用してCPUリソースを主に消費するプログラムをより速く実行することはできません.例:1つのスレッドを使用して時間を計り、別のスレッドを使用して作業を完了します.次の例では、2つのスレッドを使用します.1つは時間を計り、もう1つは実際の作業を実行します.プライマリ・スレッドは、非常に簡単なアルゴリズムを使用して素数を計算します.起動する前に、タイマースレッドを作成して起動します.このスレッドは10秒休止し、メインスレッドがチェックするフラグを設定します.10秒後にメインスレッドが停止します.共有フラグはvolatileとして宣言されていることに注意してください.
    
    /**
     * CalculatePrimes -- calculate as many primes as we can in ten seconds 
     */ 
    
    public class CalculatePrimes extends Thread {
    
        public static final int MAX_PRIMES = 1000000;
        public static final int TEN_SECONDS = 10000;
    
        public volatile boolean finished = false;
    
        public void run() {
            int[] primes = new int[MAX_PRIMES];
            int count = 0;
    
            for (int i=2; count<MAX_PRIMES; i++) {
    
                // Check to see if the timer has expired
                if (finished) {
                    break;
                }
    
                boolean prime = true;
                for (int j=0; j<count; j++) {
                    if (i % primes[j] == 0) {
                        prime = false;
                        break;
                    }
                }
    
                if (prime) {
                    primes[count++] = i;
                    System.out.println("Found prime: " + i);
                }
            }
        }
    
        public static void main(String[] args) {
            CalculatePrimes calculator = new CalculatePrimes();
            calculator.start();
            try {
                Thread.sleep(TEN_SECONDS);
            }
            catch (InterruptedException e) {
                // fall through
            }
    
            calculator.finished = true;
        }
    }
    
       

    Java 。 :

  • GUI
  • , I/O
  • , , , データへのアクセスの 。 :