サーバーサイド Javascript エンジンのコンテキストでは、ノンブロッキング I/O または非同期 I/O とは何ですか? これは、Java サーバー側の実装に対する利点として言及されているようです。
2 に答える
同期と非同期
同期実行とは、通常、コードが順番に実行されることを指します。非同期実行とは、コードに表示される順序で実行されない実行を指します。次の例では、同期操作によってアラートが順番に発生します。非同期操作では、alert(2)
2 番目に実行されるように見えますが、実行されません。
同期: 1,2,3
alert(1);
alert(2);
alert(3);
非同期: 1,3,2
alert(1);
setTimeout(() => alert(2), 0);
alert(3);
ブロッキング vs ノンブロッキング
ブロッキングとは、その操作が完了するまでそれ以降の実行をブロックする操作を指します。ノンブロッキングとは、実行をブロックしないコードを指します。与えられた例でlocalStorage
は、実行を停止して読み取りを行うため、ブロック操作です。一方、fetch
は実行が停止しないため、ノンブロッキング操作alert(3)
です。
// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);
// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);
利点
ノンブロッキングの非同期操作の利点の 1 つは、単一の CPU とメモリの使用率を最大化できることです。
同期、ブロッキングの例
同期ブロック操作の例としては、Java や PHP などの一部の Web サーバーが IO やネットワーク リクエストを処理する方法があります。コードがファイルまたはデータベースから読み取る場合、コードはそれ以降のすべての実行を「ブロック」します。その間、マシンは何もしていないスレッドのメモリと処理時間を保持しています。
そのスレッドが停止している間に他のリクエストに対応するには、ソフトウェアによって異なります。ほとんどのサーバー ソフトウェアが行うことは、追加の要求に対応するために、より多くのスレッドを生成することです。これにより、より多くのメモリが消費され、より多くの処理が必要になります。
非同期、ノンブロッキングの例
非同期の非ブロッキング サーバー (Node で作成されたものなど) は、1 つのスレッドのみを使用してすべての要求を処理します。これは、Node のインスタンスが 1 つのスレッドを最大限に活用することを意味します。作成者は、I/O とネットワーク操作がボトルネックであるという前提で設計しました。
要求がサーバーに到着すると、一度に 1 つずつ処理されます。ただし、たとえばサービス対象のコードが DB にクエリを実行する必要がある場合は、コールバックを 2 番目のキューに送信し、メイン スレッドは引き続き実行されます(待機しません)。DB 操作が完了して戻ると、対応するコールバックが 2 番目のキューから取り出され、実行が保留されている 3 番目のキューに入れられます。エンジンが他の何かを実行する機会を得ると (実行スタックが空になったときなど)、3 番目のキューからコールバックを取得して実行します。
var startTime = new Date().getTime();
var getEndTime = () => {
var tempEndTime = new Date().getTime();
var second = (tempEndTime - startTime)/1000
return `took ${second} sec...to finish\n`
}
console.log('1: start App', getEndTime())
setTimeout(()=>{
console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())
// console -> Process Order: 1 -> 3 -> 2