ホームページ  >  記事  >  Java  >  Javaスレッドの用途は何ですか

Javaスレッドの用途は何ですか

(*-*)浩
(*-*)浩オリジナル
2019-05-08 17:05:444236ブラウズ

このチュートリアルでは、スレッドの基本、つまりスレッドとは何か、スレッドがなぜ役立つのか、スレッドを使用する簡単なプログラムの作成を開始する方法について説明します。 (推奨コース: Java ビデオ チュートリアル )

スレッドとは何ですか?

ほぼすべてのオペレーティング システムは、プロセスという概念、つまり相互にある程度分離され、独立して実行されるプログラムをサポートしています。

スレッドは、プロセス内で複数のアクティビティを共存できるようにするツールです。最新のオペレーティング システムのほとんどはスレッドをサポートしており、スレッドの概念は長年にわたりさまざまな形で存在しています。 Java は、言語自体にスレッドを明示的に組み込んだ最初の主要なプログラミング言語であり、スレッドを基礎となるオペレーティング システムのツールとして扱っていませんでした。

スレッドは軽量プロセスと呼ばれることもあります。プロセスと同様に、スレッドはプログラム内の独立した同時実行パスであり、各スレッドには独自のスタック、独自のプログラム カウンタ、および独自のローカル変数があります。ただし、プロセス内のスレッドは、個別のプロセスに比べて互いに分離されにくくなります。これらは、メモリ、ファイル ハンドル、および各プロセスが持つべきその他の状態を共有します。

プロセスは複数のスレッドをサポートできます。複数のスレッドは同時に実行されているように見えますが、互いに同期していません。プロセス内の複数のスレッドは同じメモリ アドレス空間を共有します。つまり、同じ変数とオブジェクトにアクセスでき、同じヒープからオブジェクトを割り当てます。これによりスレッド間で情報を共有しやすくなりますが、同じプロセス内の他のスレッドに干渉しないように注意する必要があります。

Java スレッド ツールと API は、一見シンプルです。ただし、スレッドを効率的に使用する複雑なプログラムを作成するのはそれほど簡単ではありません。複数のスレッドが同じメモリ空間に共存し、同じ変数を共有しているため、スレッドが相互に干渉しないように注意する必要があります。

すべての Java プログラムはスレッドを使用します

すべての Java プログラムには少なくとも 1 つのスレッド (メイン スレッド) があります。 Java プログラムが開始されると、JVM はメイン スレッドを作成し、このスレッドでプログラムの main() メソッドを呼び出します。

JVM は、通常は見られない他のスレッドも作成します。たとえば、ガベージ コレクション、オブジェクトの終了、その他の JVM ハウスキーピング タスクに関連するスレッドなどです。 AWT (Abstract Windowing Toolkit) や Swing UI Toolkit などの他のツール、サーブレット コンテナー、アプリケーション サーバー、および RMI (Remote Method Invocation) も作成します。

スレッドを使用する理由

Java プログラムでスレッドを使用する理由はたくさんあります。 Swing、サーブレット、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 つの例は、アプリケーションに複数の独立したイベント駆動コンポーネントがある場合です。たとえば、アプリケーションには、イベント後の秒数をカウントダウンし、画面表示を更新するコンポーネントが含まれている場合があります。定期的に時間をチェックして表示を更新するメイン ループを使用するよりも、スレッドに何もせず、一定時間が経過して画面上のカウンターが更新されるまでスリープ状態にする方が簡単でエラーが発生しにくくなります。このように、メインスレッドはタイマーについてまったく心配する必要がありません。

非同期またはバックグラウンド処理

サーバー アプリケーションは、ソケットなどのリモート ソースから入力を取得します。ソケットから読み取るときに、現在使用可能なデータがない場合、データが使用可能になるまで SocketInputStream.read() の呼び出しはブロックされます。

シングルスレッド プログラムがソケットを読み取りたいときに、ソケットの反対側のエンティティがデータを送信しない場合、プログラムは他の処理を実行せずに永遠に待機することになります。代わりに、プログラムはソケットをポーリングしてデータが利用可能かどうかを確認できますが、これはパフォーマンスに影響するため、通常は使用されません。

ただし、ソケットから読み取るスレッドを作成した場合、このスレッドがソケットからの入力を待機している間、メインスレッドは他のタスクを実行できます。複数のスレッドを作成して、複数のソケットから同時に読み取ることもできます。こうすることで、データが利用可能かどうかを確認するために頻繁にポーリングを行わなくても、データが利用可能になったときに (待機中のスレッドがウェイクアップされると) すぐに通知を受けることができます。スレッドを使用してソケットで待機するコードも、ポーリングよりも単純でエラーが発生しにくくなります。

シンプルだが危険な場合もある

Java スレッド ツールは非常に使いやすいですが、マルチスレッドを作成するときに回避すべきリスクがいくつかあります。プログラム。

複数のスレッドが同じデータ項目 (静的フィールド、グローバルにアクセス可能なオブジェクトのインスタンス フィールド、共有コレクションなど) にアクセスする場合、データへのアクセスを調整する必要があります。全員がデータを参照できるため、互いの変更を妨げることなく一貫したビューが得られます。この目的を達成するために、Java 言語には、synchronized と volatile という 2 つのキーワードが用意されています。これらのキーワードの目的と意味については、このチュートリアルの後半で説明します。

複数のスレッドから変数にアクセスする場合、アクセスが正しく同期されていることを確認する必要があります。単純な変数の場合は、変数を volatile として宣言するだけで十分な場合がありますが、ほとんどの場合、同期が必要です。

同期を使用して共有変数へのアクセスを保護する場合は、変数がアクセスされるプログラム内のあらゆる場所で同期が使用されていることを確認する必要があります。

使いすぎないでください

スレッドはさまざまな種類のアプリケーションを大幅に簡素化できますが、スレッドを使いすぎると、プログラムのパフォーマンスと保守性が損なわれる可能性があります。スレッドがリソースを消費しました。したがって、パフォーマンスを低下させることなく作成できるスレッドの数には制限があります。

特にユニプロセッサ システムでは、複数のスレッドを使用しても、主に CPU リソースを消費するプログラムの実行速度は向上しません。

例: タイミングに 1 つのスレッドを使用し、作業を完了するために別のスレッドを使用する

次の例では、タイミングに 1 つと実際の作業の実行に 1 つずつ、計 2 つのスレッドを使用します。メインスレッドは非常に単純なアルゴリズムを使用して素数を計算します。

開始する前に、タイマー スレッドを作成して開始します。タイマー スレッドは 10 秒間スリープしてから、メイン スレッドがチェックするフラグを設定します。 10 秒後、メインスレッドが停止します。共有フラグは揮発性として宣言されていることに注意してください。

/**
 * 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 を実行する

複数のスレッドを使用する場合は、スレッド間でデータを共有するためのルールに従うように注意する必要があります。これについては、「共有」で説明します。データへのアクセス。これらすべてのルールは、「同期することを忘れない」という 1 つの基本原則に要約されます。

以上がJavaスレッドの用途は何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。