1. ホーム
  2. Web プログラミング
  3. その他全般

ブロッキング、ノンブロッキング、同期、非同期を1つの記事で理解する

2022-01-17 11:22:17

ブロッキング、ノンブロッキング、シンクロナス、アシンクロナスを理解する

まず、これらは特徴的な場面や相対的な状況で使われる用語である、ということから始めましょう、いいですか、では本題に入ります。

ブロッキング

のイメージで、休日の高速道路出口料金所のように、視覚的に理解することができる。

9つの料金所、同時にやってくる車の大波、同時に9台しか充電できない、残りの車は列の後ろで待っている、これは現実には非常に直感的な閉塞現象である。9つの料金所はボトルネックであり、おそらく次のような "ボトルネック"という言葉の理解に近いと思われる。

高速道路に次々と車が到着する1枚目の画像の効果は、実は2枚目の画像で示されたものと同じです。

OK、図を見て現象を理解しよう!なぜブロックになるのか分析してみて?

1. 定量的である。

到着車両数 - 多い

料金所数 - 9ヶ所以下

結論 カードを渡る車の数が料金所の数より多い場合、閉塞が発生する。

2. 速度について。

到着車速-速い

料金所通過速度-遅い

結論 料金所を通過する速度が車両到着速度より遅い場合、閉塞が発生する。

まとめ:ブロッキング現象は、容積差と速度差によって起こる。

なぜ体積差があるのか、その疑問について考えてみてください。

料金所の数は、合理的な計画に基づいて設置されます。1,000ブースを設置しても、高速道路から来る車は一番奥のブースまでかなり距離があり、そこまでして通行料を徴収したい車の所有者はいないでしょう。同時に、コスト的な要素も考慮する必要がある。

例えば、データベース接続プールの接続数が10と有限であるにもかかわらず、1ミリ秒間に1000回の問い合わせが必要なプログラムでは、ブロッキング現象が発生することがあります。

また、速度差は客観的なものですが、料金所も高速道路の速度に合わせて進化する必要がありますが、料金所は高速道路を走る車を高速道路以外の速度に合わせて減速させるという目的も持っています。

プログラムでは、ネットワークIOとディスクIOを経由するデータベースクエリは、同じ内容をネイティブメモリに直接取得するよりも遅い方法です。

ブロックというのは、実は客観的な現象であり、本来は回避できないものなのです。

回避できないのだから、......ノンブロッキングとは何か?

ノンブロッキング

まだ上記の例では、車両は高速道路料金所を通過し、非ブロック化は、よりETCの修正版のように、車両は高速道路に、ナンバープレートの登録を一掃し、車両は高速道路を残して、ナンバープレートの登録を一掃し、その後車両は、所有者の携帯電話は、SMSから差し引かれたETCを受け取る前に数百メートル運転した、この時点で、高速道路の通行料は完了したと考えられるされています。全体のプロセスは、滞在時間は非常に短いです、ナンバープレートの認識効率が非常に高い場合は、車のカードポールを削除することができますので、車両が滞在する必要はありません。

ドエルは必要ありません。すなわち、速度は車両の到着速度と一致します。すなわち、ブロッキングはありません。

では、閉塞感がなくなったというのは本当なのでしょうか?そんなことが可能なのでしょうか?車から見れば閉塞感がないのは事実ですが、料金徴収手続き全体から見れば、通行料が正常に請求される前に数百メートル走り出すということは、実は自動料金引き下げが遅くなって閉塞感が狭まっているのです。

閉塞感を狭め、被験者の滞留時間を短縮することがノンブロッキングの目的です。

ここまでで、とりあえずこの結論を覚えておいて、最後のまとめを文脈に残すために、まず内容の一部を折り畳む・・・・・。

シンクロナイズ

仕事から帰ってきて玄関に着いたら、次の手順でドアを開けてください。

  • 1.鍵を抜く(やはり数百の鍵の中から鍵を選ぶ必要があります。鍵のステップは無視してください)
  • 2.ドアロックホールを差し込む(磁気カードロック、指紋ロック、フェイスロックなど、鍵を使用していた時代を積極的に思い出してください)
  • 3. キーを回し、ドアを開ける

通常、3つのステップは順次依存関係にあり、どのように切り替えて分割しても、前のステップが完了するのを待つことになります。

このとき、何も支障がなければ、基本的にドアを開けるところまでは一人でやります。切り替えも、時間がかかるからです。

ドアを開ける人を主語と見なし、ドアを開けるプロセス全体を取引と見なすことができる。だから

主体が単独でトランザクションを完了させた場合、そのプロセスは同期的とみなすことができる。

社員Zhang Sanに休日メッセージを送るプログラムでは、同様の手順となる。

public static void main(String[] args) {
        // Send a holiday message to employee Zhang San with similar steps.

        // 1. first find the employee Zhang San's information
        Employee employee = findEmployee("Zhang San");

        // 2. Edit the SMS: "Happy holidays to Mr. Zhang San and happy family! "
        String message = "Wish Zhang San" + employee.getGender() + "Happy holidays and happy family! ";

        // 3. Call the SMS sending API to send SMS content to the employee's cell phone number
        sendMessage(employee.getPhone(), message);
    }

1. まず、社員張さんの情報を調べます。

2. テキストメッセージを編集します: "張さん、幸せな家庭を築いてください! "。

3. SMS送信APIを呼び出して、従業員の携帯電話番号にSMSコンテンツを送信する

トランザクション全体が1つのスレッドで順次行われる場合、それは同期操作である。

その核心は、同期が主体であることです。何を主語にするかで大きく変わります。

非同期

上記から、同期とは一人の主体が何かをすること、非同期とは複数の主体が何かをすることです。

例えば、ドアを開ける例で、主語を手に特定すると、右手がドアを開けるためにこういう手順をしている間に、左手はマスクを外しているかもしれない、どちらのことも矛盾していないのに、マスクを外した後も、頭を掻いたり、痒いところを掻いたり、左手は好きなことができる(左手は右手を壊してはいけない)。

複数の被験者が同じ瞬間に物事を行うのは非同期です。

プログラムでは、スレッド1が張三に休日メッセージを送り、スレッド2が李斯に休日メッセージを送り、スレッド3が王呉に休日メッセージを送りますが、全く問題なく、好きなようにやってください。

もちろん、複数のスレッドが同じことをする場合には 同時進行 .

問題を考えてみると、非同期が推奨されるのはどのような場合でしょうか。

複数のものが衝突せず、かつ に十分なリソースがあります。 を同時に開始すること。

例えば、ドアを開けながら頭を掻くという例で、お金を数えて左手が一瞬痺れて力が抜け、右手しか動かせないとしたら、ドアを開けながら頭を掻いても、2つのことを切り替えるのに時間がかかるだけです。

コード上では、張さんにテキストメッセージとメールの両方を送りたい場合、非同期を使うことで実現できます。

public static void main(String[] args) {
        // Send a holiday message to employee Zhang San with similar steps.

        // 1. first find the employee Zhang San's information
        Employee employee = findEmployee("Zhang San");

        // Start thread 2 to send the email
        new Thread(() -> {// Here's the asynchronous operation
            // Edit the email
            String mailMessage = "Wishing <h3>Zhang San</h3>" + employee.getGender() + "Happy holidays and happy family! ";
            // Send an email
            sendEmail(employee.getEmail(), mailMessage);
        }).start();

        // 2. edit SMS: "Happy holidays to Mr. Zhang San and happy family! "
        String message = "Wish Zhang San" + employee.getGender() + "Happy holidays, happy family! ";

        // 3. Call the SMS sending API to send SMS content to the employee's cell phone number
        sendMessage(employee.getPhone(), message);
    }

1. まず、社員張さんの情報を調べます。

2. スレッド1(メインスレッド):SMSの編集、スレッド2:電子メールの編集

3. スレッド1(メインスレッド):SMS送信、スレッド2:Eメール送信

スレッド2がstart()した後、メインスレッドは下の行に進む準備ができています。メインスレッドは、スレッド2の実行終了を待たず、つまり、異なる メインスレッドはスレッド2の終了を待たないので、非同期には一つの特徴、つまりノンブロッキングであることを意味する

非同期は、以下のように追加することができます。 コールバック ここでは詳しく説明しませんが、コールバックによって、実行時に結果をフィードバックできる強力なツールです。

概要

リソースの一部が制限されているため、ブロッキングは客観的に存在し、待ち行列を持つことがブロッキングであると単純に理解することができます。

ノンブロッキングとは、ブロッキングを絞り込んだり、遅れてもいいことを非同期で完了させたり、対象の滞留時間を短くすることが主な目的です。

最後に、料金所のノンブロッキングの例に戻りますが、車両が高速道路の外にある料金所の登録を通過した後、車両の通過に影響を与えないように別のスレッドに料金操作を行わせ、車両が数百メートル走行した時点で非同期スレッドの実行が終了し、オーナーの携帯電話にSMSが送信されます。

料金所Aの速度は遅いが、自分としてはすでに全速力で、止まっていないし、ブロックもしていないが、Bの車には止まって待っているから高速道路が来るわけで、ブロックはAとBを照らし合わせないと、誰がボトルネックになっているのかが分からない。

同期と非同期、これも対象の粒度によって相対化される。アプリケーションサービスAには100個のスレッドがあり、タスクXを共同で行っていますが、対象がスレッドの場合は非同期ですが、サービスA全体で見ると、内部で何個のスレッドがあってもタスクXを完了するだけなので、彼は同期なんです。 たった1つの主体が1つのトランザクションを完了することで、それが同期になる .

これらの考えをもとに、ブロッキングキュー、スレッドプール、コネクションプールなどのコンポーネントを理解するとよいでしょう。後で時間があるときに詳しく説明します。

以上、ブロッキング、ノンブロッキング、同期、非同期を理解するための詳細な記事を掲載しました。ブロッキング、ノンブロッキング、同期、非同期の詳細については、Scripting Houseの他の関連記事を参照してください。