Java のマルチスレッド共有変数とコラボレーション メカニズム

WBOY
リリース: 2023-04-20 15:55:20
転載
2082 人が閲覧しました

    1. プロセスとスレッド

    1. プロセスは、プログラム実行のためのリソース割り当ての最小単位です。

    プロセスとは、リソース割り当てのためのオペレーティング システム。最小単位。CPU、メモリ空間、ディスク IO など。同じプロセス内の複数のスレッドがプロセス内のすべてのシステム リソースを共有し、プロセスはそれぞれから直接独立しています。他の。プロセスは、特定のデータ セットに対して実行アクティビティを実行する、特定の独立した機能を備えたプログラムであり、システム内でリソースの割り当てとスケジューリングを行うための独立した単位です。

    プロセスとは、コンピューター上のプログラムの実行アクティビティです。プログラムを実行すると、プロセスが開始されます。明らかに、プログラムはデッドで静的ですが、プロセスはアクティブで動的です。プロセスは、システム プロセスとユーザー プロセスに分けることができます。オペレーティング システムのさまざまな機能を実行するために使用されるすべてのプロセスは、システム プロセスであり、実行状態にあるオペレーティング システム自体です。ユーザー プロセスは、ユーザーが開始したすべてのプロセスです。

    2. スレッドは CPU スケジューリングの最小単位であり、存在するにはプロセスに依存する必要があります。

    スレッドはプロセスの実体であり、CPU の基本単位です。これは、独立して動作できる通常の基本ユニットよりも小さいです。スレッド自体は基本的にシステム リソースを所有せず、実行に必要な少数のリソース (プログラム カウンター、レジスタのセット、スタックなど) のみを所有しますが、プロセスが所有するすべてのリソースを他のスレッドと共有できます。同じプロセスで。

    3. スレッドはどこにでも存在します

    すべてのプログラム、特にJavaどんなプログラムでもスレッドを作成する必要があります main 関数を開始する必要があります メイン スレッド; Java Web は、スケジュールされたタスク、タイマー、JSP および Servlet、非同期メッセージ処理メカニズム、リモート アクセス インターフェイス RM など、あらゆる監視イベントを開発しました。 onClick トリガー イベントなどはすべて、スレッドと同時実行性の知識から切り離せません。

    2. CPU コア数とスレッド数の関係

    1. マルチコア

    マルチコア: も参照CMP は、米国スタンフォード大学によって提案されたシングルチップ マルチプロセッサ (Chip Multiprocessors、CMP) に SMP# を組み合わせたものです。大規模並列プロセッサの ## (対称プロセッサ) 同一チップ内に集積され、各プロセッサが異なる処理を並列実行します。このように複数の CPU を利用して同時に並列実行するプログラムは、並列処理と呼ばれる超高速コンピューティングを実現するための重要な方向性です。

    2. マルチスレッド

    マルチスレッド:同時マルチスレッド。SMT と呼ばれます。 同じプロセッサ上の複数のスレッドを同時に実行させます。共有プロセッサ実行リソース。

    3. コアとスレッドの数

    コアとスレッドの数: 現在主流の CPU はすべてマルチコアです。オペレーティング システムはスレッドを通じてタスクを実行するため、コアの数を増やす目的はスレッドの数を増やすことです。通常、これらは 1:1 の対応関係にあり、これは クアッドコア CPU を意味します 通常、スレッドは 4 つあります。しかし、Intel がハイパー スレッディング テクノロジを導入した後、コアの数とスレッドの数は 1:2 の関係を形成しました。

    Java のマルチスレッド共有変数とコラボレーション メカニズム

    3. CPU タイム スライス ローテーションの仕組み

    普段開発をしていると、CPU コアの数に制限されていないように感じます。シングルコア CPU 上でもスレッドが使えるのはなぜでしょうか?これは、オペレーティング システムが CPU タイム スライス ローテーション メカニズムを提供しているためです。

    タイム スライス ローテーション スケジューリングは、最も古く、最も単純で、最も公平で、最も広く使用されているアルゴリズムの 1 つであり、RR スケジューリングとも呼ばれます。各プロセスには、プロセスが実行される時間であるタイム スライスと呼ばれる期間が割り当てられます。

    4. 並列処理と同時実行性

    例を見てみましょう。4 車線の高速道路 A がある場合、

    並列 車両の最大数は 4 です。高速道路で並走する車両の台数が4台未満であれば、並列走行が可能です。 CPU もこの原則に基づいており、1 つの CPU は高速道路に相当し、コアまたはスレッドの数は併走できる車両の数に相当します。複数の CPU これは、複数の高速道路があり、それぞれに複数の車線が並んでいるのと同じです。

    同時実行数について話すときは、単位時間を追加する必要があります。つまり、単位時間あたりの同時実行量はいくらでしょうか?実際には単位時間を離れても意味がありません。

    よく言われるように、一度に 2 つのことを行うことはできません。これはコンピュータでも同じです。原則として、

    CPU は、次のことを行うために 1 つのプロセスにのみ割り当てることができます。このプロセスを実行します。私たちが普段使っているコンピュータには CPU が 1 つしか搭載されておらず、つまり心臓も 1 つしかないため、多目的に使用して複数のプロセスを同時に実行できるようにするには、同時実行テクノロジを使用する必要があります。同時実行テクノロジの実装は非常に複雑ですが、最も理解しやすいのは「タイム スライス ローテーション プロセス スケジューリング アルゴリズム」です。

    1. 同時実行性

    同時実行性: は、アプリケーションが異なるタスクを交互に実行できることを意味します。たとえば、単一の CPU コアで複数のスレッドを実行することは意味しません。複数のタスクを同時に実行します。実行用に 2 つのスレッドを開いた場合、ほとんど知覚できない速度でこれら 2 つのタスクの実行を切り替え続けて、「同時実行」効果を実現します。これは、コンピューターの実行速度が高すぎるだけです。私たちが気づくのが早いです。

    2. Parallel

    Parallel: は、アプリケーションが異なるタスクを同時に実行できることを意味します。たとえば、食事とテレビの視聴を同時に行うことができます。これら 2 つのことは同時に実行できます。

    **同時実行と並列処理の違いは次のとおりです。 一方は交互に実行され、他方は同時に実行されます**

    Java のマルチスレッド共有変数とコラボレーション メカニズム

    5 , 高同時実行プログラミング

    マルチコアCPUの誕生により、マルチスレッドかつ高同時実行プログラミングがますます注目され注目を集めています。

    1. CPU リソースのフル活用

    上記の CPU の紹介から、多くのスレッド同時実行メカニズムを使用しない市場、特にサーバーに複数の CPU がある場合。プログラムの基本的なスケジューリング単位はスレッドです。スレッドは、CPU の 1 つのコアの 1 つのスレッドでのみ実行できます。i3 CPU を使用している場合、最悪でもデュアル コアと 4 スレッドの計算能力しかありません。スレッドの場合、CPU パフォーマンスの 3/4 が無駄になります。マルチスレッドを設計すると、複数の CPU の複数のコアの複数のスレッドで同時に実行できるため、CPU を最大限に活用し、パフォーマンスを削減できます。 CPU のアイドル時間を短縮し、その計算能力を発揮して同時実行性を高めます。 2. ユーザーの応答時間を短縮する

    たとえば、私たちがよく使用するダウンロード機能では、メンバーシップ バージョンでは複数のスレッドをダウンロードできるため、多くの友人が特定のメンバーシップを開くことになります。 1 つのスレッドがダウンすることを誰も許容できません。なぜですか?マルチスレッドのダウンロードが速いためです。

    プログラム開発を行うとWebページの速度が1秒速くなり、ユーザー数が多ければコンバージョン数も増加します。私たちがよく閲覧する Web ページでは、ブラウザーがページを読み込むときに、Web サイトの対応する速度を向上させるために、さらにいくつかのスレッドを開いてネットワーク リソースを読み込みます。

    マルチスレッドと高い同時実行性は、コンピュータのいたるところにあります。

    3. コードをモジュール化、非同期、シンプルにする

    たとえば、電子商取引プロジェクトを行う場合、注文したり、ユーザーにテキスト メッセージや電子メールを送信したりすることができます。分割: ユーザーにテキスト メッセージと電子メールを送信する 2 つのステップは、2 つの個別のモジュールに分割され、実行のために他のスレッドに渡されます。これにより、非同期操作が増加し、システムのパフォーマンスが向上するだけでなく、プログラムがモジュール化され、明確かつシンプルになります。

    6. マルチスレッドに関する注意事項

    1. スレッド間のセキュリティ

    同じプロセス内の複数のスレッドはリソースを共有します。つまり、すべてのスレッドがリソースにアクセスできます。同じメモリアドレスにあります。

    例: 各スレッドでグローバル変数と静的変数に対する読み取り操作のみがあり、書き込み操作がない場合、一般に、このグローバル変数はスレッドセーフです。複数のスレッドがそれを実行する場合、同時に、書き込み操作では通常、スレッドの同期を考慮する必要があります。そうしないと、スレッドの安全性が影響を受ける可能性があります。

    2. スレッド間のデッドロック

    スレッド間のセキュリティ問題を解決するために、Java のロック機構が導入されていますが、注意しないと Java スレッドのデッドロックが発生します。マルチスレッドの問題。異なるスレッドがロックをまったく解放できないのを待っているため、すべての作業を完了できなくなります。

    ナイフとフォークを共有して交代で食事をしなければならない 2 人のお腹を空かせた人がいるとします。二人ともナイフとフォークを共有して 2 つのロックを取得する必要があります。スレッド A がナイフを取得し、スレッド B がフォークを取得したとします。スレッド A はフォークを待つためにブロッキング状態に入り、スレッド B はスレッド A が所有するナイフを待ちます。これは単なる不自然な例であり、実行時に検出するのは困難ですが、この種の状況は常に発生します。

    3. スレッドが多すぎると、サービス リソースが枯渇し、クラッシュが発生します。

    スレッドが多すぎると、システムが大量のスレッドを作成し、システム全体が消費される可能性があります。メモリと CPU の「遷移スイッチング」によりシステムがクラッシュする では、この種の問題はどのように解決すればよいでしょうか?

    ファイル説明など、一部のシステム リソースは制限されています。マルチスレッド プログラムでは、各スレッドがそのようなリソースを 1 つ必要とする可能性があるため、リソースが不足する可能性があります。スレッドの数が非常に多い場合、またはリソースの候補スレッドの数が使用可能なリソースの数を大幅に超える場合は、リソース プールを使用するのが最善です。最良の例の 1 つはデータベース接続プーリングです。スレッドはデータベース接続を使用する必要があるときは常に、プールからデータベース接続を取得し、使用後にプールに返します。
    リソース プールはリソース ライブラリとも呼ばれます。

    マルチスレッドアプリケーションの開発には注意すべき点がたくさんありますが、その危険性を今後の作業でゆっくりと理解していただければ幸いです。

    7. マルチスレッドに関する注意事項

    スレッドは互いに協力して特定の作業を完了します。例: 1 つのスレッドがオブジェクトの値を変更し、別のスレッドがその変更を感知して対応する処理を実行します。操作。プロセス全体が 1 つのスレッドで開始され、最後の実行は別のスレッドで行われます。前者はプロデューサーであり、後者はコンシューマです。このモデルは、「何を」と「どのように」を分離します。簡単な方法は、コンシューマ スレッドを継続的にループさせて、ループ内で満たされていない条件を設定しながら、変数が期待を満たしているかどうかを確認することです。条件が満たされた場合は、while ループを終了してコンシューマーの作業を完了します。

    しかし、次のような問題があります。

    • 適時性を確保するのが難しい。

    • オーバーヘッドを削減するのは困難です。スリープ時間を 1 ミリ秒などに短縮すると、コンシューマは状態の変化をより迅速に検出できますが、より多くのプロセッサ リソースが消費され、不必要な無駄が発生する可能性があります。

    待機/通知メカニズム: は、1 つのスレッド A がオブジェクト O の wait() メソッドを呼び出して待機状態に入り、別のスレッド B がオブジェクト O を呼び出すことを意味します。 Notice() または NoticeAll() メソッドを使用すると、スレッド A は通知を受信した後、オブジェクト O の wait() メソッドから戻り、以降の処理を実行します。上記の 2 つのスレッドは、オブジェクト O を介して対話を完了します。オブジェクト上の wait() と Notice/notifyAll() の間の関係は、待機側と通知側の間の対話を完了するために使用されるスイッチ信号のようなものです。

    notify(): wait メソッドからオブジェクトが戻るのを待っているスレッドに通知します。リターンの前提は、スレッドがオブジェクトのロックを取得しており、ロックを取得しているスレッドが存在しないことです。ロックを取得したため、再度 WAITING 状態に入ります。

    notifyAll(): オブジェクトを待機しているすべてのスレッドに通知します

    wait():このメソッドを呼び出すスレッドは待機状態に入ります。別のスレッドからの通知を待機するか、中断された場合にのみ戻ります。wait() メソッドを呼び出した後、オブジェクトのロックが解放されることに注意してください。

    wait(long): タイムアウトし、一定時間待機します。ここでのパラメータ時間はミリ秒です。これは、最大 n ミリ秒待機することを意味します。通知がない場合は、タイムアウトしてリターン。

    wait (long, int): タイムアウトをより細かく制御するには、ナノ秒に達する可能性があります。

    待機と通知の標準的なパラダイムは次のとおりです。次に待機者が続きます。 以下の原則。

    • #オブジェクトのロックを取得します。

    • 条件が満たされない場合は、オブジェクトの wait() メソッドを呼び出し、通知を受けた後も条件を確認します。

    • 条件が満たされると、対応するロジックが実行されます。

    Java のマルチスレッド共有変数とコラボレーション メカニズム

    #通知側は次の原則に従います:

      ロックを取得するオブジェクトの。
    • #条件を変更します。
    • オブジェクトを待機しているすべてのスレッドに通知します。

    wait() および Notice() シリーズのメソッドを呼び出す前に、スレッドはオブジェクトのオブジェクトレベルのロックを取得する必要があります。同期のみ可能です。メソッドまたは同期ブロックで wait() メソッドと Notice() 一連のメソッドを呼び出します。wait() メソッドに入った後、現在のスレッドはロックを解放します。wait() から戻る前に、スレッドは競合します。他のスレッドと連携してロックを再取得し、notify() を実行します。一連のメソッドのスレッドが、notifyAll を呼び出した同期されたコード ブロックを終了した後、競合します。スレッドの 1 つがオブジェクト ロックを取得すると、そのスレッドは実行を継続します。スレッドが同期されたコード ブロックを出てロックを解放した後、ウェイクアップされている他のスレッドがロックを取得するために競合し続け、ウェイクアップされたすべてのスレッドがなくなるまで継続されます。実行を完了しました。 Java のマルチスレッド共有変数とコラボレーション メカニズム

    notify と notificationAll を使用するべき人

    notifyAll() はできるだけ使用してください。notify() は 1 つのスレッドしか起動しないため、注意して使用してください。 、ウェイクアップされるスレッドがウェイクアップする必要があるスレッドであることを確認することはできません。

    以上がJava のマルチスレッド共有変数とコラボレーション メカニズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    関連ラベル:
    ソース:yisu.com
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    人気のチュートリアル
    詳細>
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート