の

「こんにちは、アミーゴ!」

「wait-notify について詳しく説明したいと思います。wait-notify メソッドは、スレッドが対話するための便利なメカニズムを提供します。また、スレッド対話のための複雑な高レベルのメカニズムを構築するために使用することもできます。」

「小さな例から始めます。Web サイトを通じてユーザーが作成したさまざまなタスクを実行する必要があるサーバー用のプログラムがあるとします。ユーザーはさまざまなタイミングでさまざまなタスクを追加できます。タスクはリソースを大量に消費しますが、サーバーの 8 -core プロセッサーは対応できます。サーバー上でどのようにタスクを実行すればよいでしょうか?」

「まず、プロセッサ コアと同じ数のワーカー スレッドのグループを作成します。各スレッドは独自のコアで実行できます。スレッドは互いに干渉せず、プロセッサ コアも干渉しません。何もせずに座っていてください。」

「2 番目に、ユーザーのタスクが追加されるキュー オブジェクトを作成します。さまざまな種類のタスクはさまざまなオブジェクトに対応しますが、それらはすべて Runnable インターフェイスを実装しているため、タスクを実行できます。」

「タスクオブジェクトの例を教えていただけますか?」

"見てみな:"

run() メソッドが呼び出されたときに n 階乗を計算するクラス
class Factorial implements Runnable
{
 public int n = 0;
 public long result = 1;

 public Factorial (int n)
 {
  this.n = n;
 }

 public void run()
 {
  for (int i = 2; i <= n; i++)
   result *= i;
 }
}

"ここまでは順調ですね。"

「わかりました。それでは、キュー オブジェクトがどのように見えるべきかを調べてみましょう。それについて何か教えていただけますか?」

「スレッドセーフである必要があります。ユーザーからタスク オブジェクトを受け取るスレッドによってタスク オブジェクトが読み込まれ、タスクはワーカー スレッドによって取得されます。」

「そうだね。それで、一時的にタスクがなくなったらどうする?」

「その場合、ワーカー スレッドは、さらにスレッドが増えるまで待機する必要があります。」

「そのとおりです。ここで、これらすべてを 1 つのキューで構築できると想像してください。確認してください。」

タスクキュー。タスクがない場合、スレッドはスリープ状態になり、タスクが表示されるまで待機します。
public class JobQueue
{
 ArrayList jobs = new ArrayList();

 public synchronized void put(Runnable job)
 {
  jobs.add(job);
  this.notifyAll();
 }

 public synchronized Runnable getJob()
 {
  while (jobs.size() == 0)
   this.wait();

  return jobs.remove(0);
 }
}

「タスク リストが空かどうかをチェックするgetJobメソッドがあります。その後、スレッドはリストに何かが表示されるまでスリープ (待機) 状態になります。」

「リストに新しいタスクを追加できるputメソッドもあります。新しいタスクが追加されるとすぐに、notifyAll メソッドが呼び出されます。このメソッドを呼び出すと、getJob メソッド内でスリープ状態になっていたすべてのワーカー スレッドが目覚めます。」

「待機メソッドと通知メソッドがどのように機能するかをもう一度思い出していただけますか?」

「wait メソッドは、同期されたブロック内、ミューテックス オブジェクト上でのみ呼び出されます。私たちの場合: これです。さらに、次の 2 つのことが起こります。

1)スレッドはスリープ状態になります。

2)スレッドはミューテックスを一時的に解放します (ウェイクアップするまで)。

「その後、他のスレッドが同期ブロックに入り、同じミューテックスを取得できるようになります。」

notifyAllメソッドは、ミューテックス オブジェクトの同期ブロック内でのみ呼び出すこともできます。私たちの場合はこれです。さらに、次の 2 つのことが起こります。」

1)このミューテックス オブジェクトを待機しているすべてのスレッドが起動されます。

2) 現在のスレッドが同期ブロックを出ると、起動されたスレッドの 1 つがミューテックスを取得し、その作業を継続します。ミューテックスを解放すると、起動した別のスレッドがミューテックスを取得します。

「これはバスとよく似ています。乗車して運賃を支払おうと思っても、運転手がいません。それで、あなたは「眠ってしまう」のです。最終的にバスは満員になりますが、まだ運賃を渡す人がいません。そして運転手は、到着して、「運賃をお願いします」と言います。そしてこれが始まりです…」

「興味深い比較ですね。でも、バスって何でしょうか?」

「フリオが説明してくれました。21世紀には奇妙なものが使われていました。」