blog

Java高並行性シリーズ 並行性の世界へ

"\nこの記事は、Java並列処理を始めるためのものです。\n\nもし参考になるなら、❥を忘れないでください。\n"\n\n2014年末のAvoiding ping pongフォーラムで、"リーナス・...

Nov 22, 2020 · 8 min. read
シェア

皆さんこんにちは、インターネット業界で蔡武チョイを目指すチョイです。軟派にも硬派にもなれる、好きなら軟派、淫するなら硬派!"デッドビート~、読後は三文芝居を忘れずに!"

"

この記事は、Java並列処理を始めるためのものです。

参考になりましたら、 」をお忘れなく❥❥。

"

2014年 末のAvoiding ping pongフォーラムで、"Linus Torvalds""クソ並列主義は忘れろ!"と言ったとき、まったく異なる指摘をしました

このメッセージを見たとき、私は急に胸が締め付けられるような気持ちになりました。

しかし、蔡を料理しないようにしたい、物事が単純ではないことがわかりました〜開発は、プログラムに対処するためにマルチスレッドを使用しようとしている、プログラムを高速化するためではなく、このTMは、私は難しいああなります!

「並行プログラムは、直列プログラムよりもビジネスのニーズに適応しやすい

簡単に言うと、3人家族で、あなたは学校へ行き、お母さんは家で家事をし、お父さんはお金を稼ぐために働きに出ます。同時に3人が生活を充実させるためにいろいろなことをしているわけです。であれば、マルチタスクをこなす人、3人分の仕事を1人でこなす、これができると言うことですね。

専門的に言えば:Java仮想マシンは、メインスレッドに加えて、メイン関数を実行するだけでなく、JITコンパイル、ごみ収集などを行うには、非常に忙しいです。仮想マシン内のこれらの事は一緒に動作し、別のスレッドであること、各タスクは、理解しやすく、維持するために、互いに独立しています。

"今でも覚えているかどうかはともかく、忘れることはあり得ないので、忘れなければ、うまく使えるように頑張るしかない"、さあ、ナックの手を取って、一緒に克服しましょう!

いくつかの重要な概念

同期と非同期

で、単一のメソッド呼び出しを記述するためによく使われます。

同期(Synchronous): 同期メソッドの呼び出しが開始されると、呼び出し元はメソッドの実行が終了するまで待機しなければなりません。

非同期: 非同期メソッドはメッセンジャーのようなものです。いったんメソッド呼び出しが開始されると、メソッド呼び出しはすぐに戻り、呼び出し元はその後の処理を続けることができます。メソッドの実行は通常別のスレッドで行われ、呼び出し元の作業の邪魔になることはありません。

シンクロナスとは、切符を買うために駅に行き、行列に並び、行列が来たら切符を買ってから他のことをする、ということです。非同期式とは、オンラインで切符を買い、支払いを済ませれば切符は手元に届き、その間に他のことができるということです。

並行処理と並列処理

この2つは特に混乱しやすい概念です。

並列性:複数のタスクの真の意味での 同時実行

同時実行:複数のタスクが交互に実行され、複数のタスクが互いに直列に実行されることがあります。

システム内にCPUが1つしかなく、マルチプロセッシングやマルチスレッドでタスクが実行される場合、真の並列処理はできません。

クリティカルゾーン

は、複数のスレッドが使用できるパブリックリソースや共有データを表すために使用されます。ただし、一度に使用できるのは 1 つのスレッドのみで、クリティカル エリア リソースが占有されると、他のスレッドがこのスレッドを使用するには待機する必要があります。

簡単に言うと、プリンターがあり、プリンターは一度に1つのタスクしか実行できないので、2人が同時にプリンターを使いたい場合、生徒Aは生徒Bがプリンターを使い終わるのを待ってから、自分の資料を印刷することができます。

ブロッキングとノンブロッキング

複数のスレッド間の相互作用を記述するために使用されます。

ブロッキング: 学生Aがプリンターを占有し、学生Bがプリンターを使いたい場合、学生Aがプリンターを使い終わるまで待たなければなりません。学生Aがプリンターを使い続け、他の学生に使わせない場合、他の学生は正常な作業ができなくなります。

ノンブロッキング: 学生Aはプリンターを使用していますが、学生Bの通常の作業を妨げることはありません。

デッドロック:図に示すように、4つのスレッドが互いに待ち合い、リングを形成しています。この状態は永遠に続き、誰もリングから抜け出すことができません。

饑餓:食堂の窓の中の学生がご飯をやって、列の後ろのBの学生は、この時間はC、Dが来て......。いくつかの学生が直接Bの学生の後ろのキューに挿入され、後続の学生は、Bの学生が食事を再生することはできませんという結果につながるBの学生の前にキューを挿入し続け、現象が発生します。また、スレッドがキーリソースを占有されている場合、このリソースを必要とする他のスレッドが正常に実行することはできません、その結果、このような状況も一種です。

ライブロック:廊下、A学生が通過したい、B学生の顔の上を歩くが、それは2つの学生がお互いにブロックすることは非常に残念ですが、その後、A学生が道を作るために右に、B学生も道を作るために右に、A学生が道を作るために左に、B学生も道を作るために左に、繰り返した後、最終的に道を作るでしょう。しかし、2つのスレッドがこのような状況に遭遇すると、2つのスレッドは人間のように知的ではなく、お互いにブロックし合い、リソースは2つのスレッドの間で跳ね返り続け、その結果、どちらのスレッドもリソースを得ることができなくなり、このような状況になります。

同時並行レベル

それは次のように分けられます:

  • 妨害

スレッドがブロッキングしている場合、現在のスレッドは他のスレッドがリソースを解放するまで実行を続けることができません。例えば、"synchronized""reentrant locking"使用すると、ブロッキングスレッドになります。

  • ノー・ハンガー

スレッド間に優先順位がある場合、スレッドスケジューリングは常に優先順位の高いスレッドを優先します。

非フェアロック:システムは優先度の高いスレッドをキューに入れることができますが、優先度の低いスレッドが飢餓状態に陥る可能性があります。

公平なロック:先着順で、新参者はどんなに優先順位が高くても並ばなければなりません。

  • アクセシビリティ

アクセシビリティはノンブロッキングスケジューリングの最も弱い形態です。障害なく実行される2つのスレッドが、クリティカルゾーンの問題で1つをハングさせることはありません。

もしイエスなら、イエスです。アクセス可能なマルチスレッドプログラムはスムーズに実行されません。クリティカルゾーンでリソースの深刻な競合が発生すると、すべてのスレッドが処理をロールバックし、その結果、どのスレッドもクリティカルゾーンから抜け出せなくなります。

アクセシビリティ」の実現可能性は、ポリシーを使用することで実現できます。操作が完了したら、このフラグを再度読み出して、変更されたかどうかを判断します。矛盾している場合は、操作中にリソースが他のスレッドと競合している可能性があり、操作を再試行する必要があることを意味します。

  • ロック解除

ロックフリーの並列処理はアクセス可能性がすべてです。ロックフリーの場合、どのスレッドもクリティカルゾーンにアクセスすることができますが、ロックフリー並列では、1つのスレッドが必ず有限ステップ数で処理を完了し、クリティカルゾーンを出ることができることが保証される」という違いがあります

  • 待ったなし。

ロックフリーはスレッドが有限のステップ数で処理を完了し、クリティカルゾーンを離れることができることを要求するだけですが、wait-freeはロックフリーをさらに拡張し、すべてのスレッドが有限のステップ数で完了しなければならないことを要求します。

典型的なノーウェイト構造はRCU」で、読み出しは制御なしで読み出し、データを書き込むときはまず元データのコピーを入手し、変更を加え、それからデータを書き戻せ

JMM

JMM」の 主要な技術的ポイントは、マルチスレッドの原子性、可視性、秩序性を中心に構築されています。

原子性

原子性とは、操作が中断されないことを意味します。複数のスレッドが一緒に実行されている場合でも、一度操作が開始されると、他のスレッドによって中断されることはありません。

簡単に言うと、静的なグローバル変数iがあり、2つのスレッドが同時にそれに値を代入し、スレッドAがそれに値1を代入し、スレッドBがそれに値2を代入した場合、どのように操作してもiの値は1か2のどちらかになり、2つのスレッド間で干渉することはありません。

int型の 代わりに long 型を使用した場合、問題が発生する可能性があります。これは、"long"型の読み書きはアトミックではないからです。

視認性

可視性とは、あるスレッドが共有変数の値を変更すると、他のスレッドはその値が変更されたことを直ちに認識できるということです。シリアル・システムでは、どの操作ステップでも変数を変更した場合、後続のステップで読み込まれるのは変更された変数でなければならないため、可視性の問題は存在しません。

"2つのスレッドが変数を共有しており、コンパイラの最適化またはハードウェアの最適化により、スレッドBがキャッシュまたはレジスタに設定することで変数を最適化しているため、スレッドAが変数を変更しても、スレッドBはその変更に気づかず、キャッシュに保存された古い値を読み込むことになります。"

秩序

スレッドの実行コードでは、タスクコードは常に最初から最後まで連続して実行されるのが通例です。もちろん、これはプログラム全体が1つのスレッドだけ」の場合です。マルチスレッドプログラムの場合、プログラムの実行は"順不同"なることがあります。これは、プログラムの実行が行われ、並べ替えられた命令が元の命令と同じ順序にならないことがあるからです。

スレッドAが最初にwriter()メソッドを実行し、その後にスレッドBがreader()メソッドを実行し、命令の並べ替えが発生した場合、スレッドBはi = a + 1を実行するときにa = 1を見ることができません。

スレッドにとって、命令が実行される順序は一貫していなければなりません。命令の並び替えは、直列的な意味的一貫性を確保する」という前提に基づいています。

  • プログラム順序の原則:単一スレッド内で意味的直列性が保証されます。
  • 揮発性ルール:揮発性変数への書き込みは読み込みより先に行われるため、揮発性変数の可視性が確保されます。
  • ロック・ルール:ロック解除は必ずロック前に行われます。
  • 伝達性:AはBに先行し、BはCに先行。
  • スレッドの start() メソッドは、各アクションの前にあります。
  • スレッドへの割り込み interput() は、割り込まれたスレッドのコードの前に置かれます。
  • オブジェクトのコンストラクタの実行は、finalize() メソッドの前に終了します。
"

今日もう少し努力すれば、明日のおねだりは少しは減るでしょう!

"
Read next

フリップブックアニメーションのシンプルなjs実装

![フリップブック]\nフリップブックを実現するための簡単なjsを介して\n<!DOCTYPE html>\n<html lang="ja">.\n<head>\n <meta cha

Nov 22, 2020 · 11 min read