Javaスレッディングの概念<br />他のほとんどのコンピューター言語とは異なり、Javaは組み込みのマルチスレッドプログラミングをサポートしています。
マルチスレッドプログラムには、同時に実行される2つ以上の部品が含まれています。プログラム内の各部分はスレッドと呼ばれ、各スレッドには独立した実行パスがあります。したがって、マルチスレッドはマルチタスクの特別な形式です。
実際にはすべての最新のオペレーティングシステムでサポートされているため、マルチタスクを知っておく必要があります。ただし、マルチタスクには、プロセスベースとスレッドベースの2つの異なるタイプがあります。 2つの違いを理解することは非常に重要です。
多くの読者にとって、プロセスベースのマルチタスクはより馴染みのある形式です。プロセスは基本的に実行プログラムです。したがって、プロセスベースのマルチタスクは、コンピューターが2つ以上のプログラムを同時に実行できるようにすることで特徴付けられます。たとえば、プロセスベースのマルチタスクを使用すると、テキストエディターの使用中にJavaコンパイラを同時に実行できます。プロセスベースのマルチタスクでは、プログラムはスケジューラによって割り当てられたコードの最小単位です。
スレッドベースのマルチタスク環境では、スレッドは最小の実行ユニットです。これは、プログラムが2つ以上のタスクの関数を同時に実行できることを意味します。たとえば、テキストエディターは、印刷中にテキストをフォーマットできます。したがって、マルチプロセスプログラムは「ビッグピクチャーズ」を処理し、マルチスレッドプログラムは詳細を処理します。
マルチスレッドプログラムには、マルチプロセスプログラムよりも少ない管理費用が必要です。プロセスは、独自の独立したアドレススペースを必要とするヘビー級のタスクです。プロセス間通信は高価で制限されています。プロセス間の変換も非常に費用がかかります。一方、スレッドは軽量のプレイヤーです。彼らは同じアドレス空間を共有し、同じプロセスを一緒に共有します。スレッド間通信は安価であり、スレッド間変換も低コストです。 Javaプログラムがマルチプロセスタスク処理環境を使用する場合、マルチプロセスプログラムはJavaによって制御されず、マルチスレッドはJavaによって制御されます。
マルチスレッドは、アイドル時間が最小限に抑えられているため、最大のCPU使用率で効率的なプログラムを作成するのに役立ちます。これは、自由時間が公開されているため、Javaで実行されるインタラクティブなネットワーク相互接続環境にとって重要です。たとえば、ネットワークのデータ送信レートはコンピューターの処理能力よりもはるかに低く、ローカルファイルシステムリソースの読み取り速度はもちろん、ユーザー入力よりもはるかに低いです。 。従来のシングルスレッド環境では、次のステップを実行する前に、プログラムはそのようなタスクごとに完了するのを待つ必要があります。ただし、CPUには多くの自由時間があります。マルチスレッドを使用すると、この自由時間を最大限に活用できます。
Javaスレッドモデル
Javaランタイムシステムは、さまざまな方法でスレッドに依存しており、すべてのクラスライブラリデザインではマルチスレッドが考慮されています。実際、Javaはスレッドを使用して環境全体を非同期にします。これにより、CPUループの無駄を防ぐことにより、無効な部分を減らすことができます。
マルチスレッド環境の利点をよりよく理解するために、そのコントロールと比較できます。単一スレッドシステムの処理方法は、ポーリングと呼ばれるイベントループメソッドを使用することです。このモデルでは、シングルスレッドコントロールが無限のループで実行され、一連のイベントを投票して、次に何をすべきかを決定します。ポーリングデバイスがネットワークファイルを読み取る準備ができているという信号を返すと、イベントループスケジューリングコントロールは適切なイベントハンドラーに管理します。イベントハンドラーが戻るまで、システムに他のイベントは発生しません。これはCPU時間を無駄にします。これにより、プログラムの一部がシステムを独占的に占有し、他のイベントの実行を防ぎます。一般に、単一の読み取り環境では、リソースを待っている間にスレッドがブロック(ブロック、実行を中断)すると、プログラム全体の実行が停止します。
Javaマルチスレッドの利点は、メインループ/ポーリングメカニズムをキャンセルすることです。プログラムの他の部分に影響を与えることなく、スレッドを一時停止できます。たとえば、スレッドがネットワークからデータを読み取るとき、またはユーザー入力を待機するときに生成されるアイドル時間は、他の場所で使用できます。マルチスレッドにより、システム全体を一時停止することなく、各フレームギャップでライブループを1秒間スリープできます。 Javaプログラムにはスレッドブロックがあり、1つのスレッドのみが吊り下げられ、他のスレッドは実行され続けます。
いくつかの状態にスレッドが存在します。スレッドは実行されている可能性があります。 CPU時間を取得する限り実行できます。実行中のスレッドを一時停止し、その実行を一時的に中断することができます。中断されたスレッドは、リソースを待っている間にスレッドをブロックすることができます。
いつでも、スレッドが終了することができ、すぐに操作を中断します。終了すると、スレッドを復元できません。
スレッドの優先順位
Javaは、各スレッドを優先順位付けして、他のスレッドと比較した場合にスレッドを処理する方法を決定します。スレッドの優先度は、スレッド間の優先関係を詳述する整数です。絶対的な値として、優先度は無意味です。代わりに、スレッドの優先度を使用して、1つの実行スレッドから別のスレッドに切り替える時期を決定します。これは「コンテキストスイッチ」と呼ばれます。コンテキスト変換の発生を決定するルールは単純です。
スレッドは自動的に制御を放棄できます。未定のI/Oの場合、睡眠またはブロッキングは明示的な譲歩によって行われます。この仮定では、他のすべてのスレッドが検出され、実行する準備ができている最優先スレッドがCPUに付与されます。
スレッドは、優先度の高いスレッドで先取りできます。この場合、低優先度のスレッドは積極的にあきらめません。プロセッサは最初に占有されます - それが何をしていても - プロセッサは高優先度のスレッドで占められています。基本的に、優先度の高いスレッドが実行されると、実行されます。これは優先マルチタスクと呼ばれます。
同じ優先度の2つのスレッドがCPUサイクルを競う場合、状況は少し複雑です。 Windows 98などのオペレーティングシステムの場合、同等の優先度のあるスレッドは、ループモードで時間を自動的に除算します。 Solaris 2.xなどの他のオペレーティングシステムの場合、優先度のスレッドは、ピアに対して自動的に放棄されます。そうでない場合、他のスレッドは実行されません。
警告:異なるオペレーティングシステム上のより低い優先度スレッドのコンテキスト変換により、エラーが生成される場合があります。
同期
マルチスレッドはプログラムに非同期行動を導入するため、必要なときに同期を強化する方法がなければなりません。たとえば、2つのスレッドを相互に通信し、リンクされたリストのシーケンスなどの複雑なデータ構造を共有する場合は、それらが互いに矛盾しないことを確認するための何らかの方法が必要です。つまり、別のスレッドがリンクリストからデータを読み取る間、1つのスレッドがデータの書き込みを防ぐ必要があります。この目的のために、Javaは、プロセス間同期の古いモデルに基づいて別の方法を実装します:モニター。管理プロセスは、Carhoareによって最初に定義された制御メカニズムです。
管理プロセスは、1つのスレッドのみを制御する小さなボックスと考えることができます。スレッドがパイプに入ると、すべてのスレッドは、スレッドがパイプを出るまで待つ必要があります。このようにして、管理を使用して、共有リソースが複数のスレッドによって操作されないようにすることができます。
多くのマルチスレッドシステムは、管理プロセスを、プログラムが明確に参照し、動作させる必要があるオブジェクトと見なしています。 Javaは明確なソリューションを提供します。代わりに「モニター」クラスはありません。各オブジェクトには、オブジェクトの同期メソッドが呼び出されたときに自動的にロードされます。スレッドが同期方法に含まれると、同じオブジェクトの同期方法を呼び出すことはできません。これにより、同期サポートが言語に組み込まれているため、非常に明確で簡潔なマルチスレッドコードを作成できます。
メッセージ配信
プログラムをいくつかのスレッドに分割した後、各スレッド間の接続を定義する必要があります。他のほとんどの言語で計画するときは、スレッド間通信を確立するためにオペレーティングシステムに依存する必要があります。これは確かにコストを増加させます。ただし、Javaは、すべてのオブジェクトが持っている事前定義された方法を呼び出すことにより、マルチスレッド間で話すためのクリーンで低コストの方法を提供します。 Javaのメッセージングシステムにより、スレッドはオブジェクトの同期メソッドを入力し、他のスレッドが明示的に通知するまで待機できます。
スレッドクラスと実行可能なインターフェイス
Javaのマルチスレッドシステムは、スレッドクラス、その方法、およびその共同企業インターフェイスが実行可能になっています。スレッドクラスは、スレッドの実行をカプセル化します。実行中のスレッドの状態を直接参照することはできないため、プロキシを介して処理する必要があるため、スレッドインスタンスが生成されます。新しいスレッドを作成するには、プログラムがスレッドを拡張するか、実行可能なインターフェイスを実装する必要があります。
スレッドクラスは、スレッドの管理に役立ついくつかの方法を定義します。この章で使用されている方法は、テーブルに示されています。