Javaでのオブジェクトのモニターの意味は何ですか?なぜこの言葉を使うのですか?


86

Javaスレッドに関する記事を読んでいると、「現在のスレッドはこのオブジェクトのモニターの所有者です」という表現に気付くことがよくあります。私は意味を理解します:スレッドはオブジェクトを操作する権利を取得します。しかし、なぜ「オブジェクトのロック」の代わりに「オブジェクトのモニター」というフレーズを使用するのか、私は困惑していますか?

簡単に言えば、「モニター」という言葉の意味がわかりません。質問は奇妙で単純かもしれません。しかし、私は誰もがそれを解決するのを手伝ってくれることを願っています。3ks


1
一つだけであるため1 @ulmangtは、実際にあなたの質問に答えるために:私たちは、「モニター」それらを呼び出すためホーアは、1974年に戻ってそれらを何と呼ばれることの
スローソロモン

回答:


51

しかし、なぜ「オブジェクトのロック」の代わりに「オブジェクトのモニター」という言葉を使用するのか、私は困惑しています。

このコンテキストで使用される「モニター」という用語を説明するリンクについては、ulmangtの回答を参照してください。ご了承ください:

「モニターは、Per BrinchHansenとCARHoareによって発明され、BrinchHansenのConcurrentPascal言語で最初に実装されました。」

(出典:ウィキペディア

「ロック」ではなく「モニター」という用語を使用するのはなぜですか。厳密に言えば、これらの用語は異なる意味を持ちます...特に、本来の使用目的で使用する場合はなおさらです。

  • 「ロック」とは、特定のロックプロパティを維持する取得および解放プリミティブを持つものです。例:専用またはシングルライター/マルチリーダー。

  • 「モニター」は、常に1つのスレッドのみがコードの特定のセクション(または複数のセクション)を実行できるようにするメカニズムです。これは、ロック(および、スレッドが条件が満たされるのを待機したり、他のスレッドに通知を送信したりできる「条件変数」)を使用して実装できますが、単なるロックではありません。実際、Javaの場合、モニターが使用する実際のロックには直接アクセスできません。(Javaの場合のように、他のスレッドが取得するのを防ぐために「Object.lock()」と言うことはできません。Lockインスタンスの場合の。)

要するに、もし人が衒学的であるとすれば、Javaが提供しているものを特徴づけるために、「モニター」は実際には「ロック」よりも良い用語です。しかし実際には、両方の用語はほぼ同じ意味で使用されます。



9

Java仮想マシンの内部からの引用

Java仮想マシンのスレッドは、モニター領域の先頭に到達したときにロックを要求します。Javaには、同期ステートメントと同期メソッドの2種類のモニター領域があります。

モニター

モニターは、一度に1つのスレッドだけが占有できる特別な部屋が1つある建物のようなものです。部屋には通常、いくつかのデータが含まれています。スレッドがこの部屋に入る時から出る時まで、スレッドは部屋のすべてのデータに排他的にアクセスできます。モニタービルに入るのを「モニターに入る」といいます。建物内の特別室に入るのを「モニターの取得」といいます。部屋を占有することを「モニターを所有すること」と呼び、部屋を離れることを「モニターを解放すること」と呼びます。建物全体を離れることを「モニターの終了」と呼びます。

モニターは、1ビットのデータに関連付けられるだけでなく、1つ以上のコードビットに関連付けられます。この本では、モニター領域と呼びます。

前述のように、この言語には、プログラム内のモニター領域を識別する2つの組み込みの方法があります。同期ステートメントと同期メソッドです。同期の相互排除の側面を実装するこれらの2つのメカニズムは、Java仮想マシンの命令セットによってサポートされています。

ロック

モニターの相互排除機能を実装するために、Java仮想マシンはロック(ミューテックスと呼ばれることもあります)を各オブジェクトおよびクラスに関連付けます。ロックは、一度に1つのスレッドだけが「所有」できる特権のようなものです。

1つのスレッドで、同じオブジェクトを複数回ロックできます。Java仮想マシンは、オブジェクトごとに、オブジェクトがロックされた回数のカウントを維持します。ロック解除されたオブジェクトのカウントはゼロです。スレッドが初めてロックを取得すると、カウントは再び1に増加します。スレッドが同じオブジェクトのロックを取得するたびに、カウントが再びインクリメントされます。


6

synchronized周りのブロックobjectは、オブジェクトのロックを制御するモニターです。ここに例があります

synchronized (object) {
   while (<condition does not hold>)
      object.wait(timeout);
   ... // Perform action appropriate to condition
}

4

この質問に答えるのは遅いですが、役に立つ場合に備えて追加することを考えました。
これは、非同期Javaメソッド内のJavaコードの同期ブロックです。

public void add(int value){
synchronized(this){
      this.count += value;
   }
}

この例では、addメソッドが呼び出されるインスタンスである「this」が使用されています。同期インスタンスメソッドは、それが属するオブジェクトをモニターオブジェクトとして使用します。
=>同じモニターオブジェクトで同期されたJavaコードブロック内で実行できるスレッドは1つだけです。


3

Java仮想マシンは、モニターを使用してマルチスレッドをサポートします。モニターは、スレッドの実行中の相互排除(ここで「ロック」が登場します)とスレッド間通信の手段としての調整(ここでオブジェクトの待機メソッドと通知メソッドが登場します)の2つの概念を通じてこれを実現します。

「InsideJVM」から次の部分を読むと、この疑問が解消されます。ここで非常にうまく説明されていますか(第20章、スレッドの同期)-

https://www.artima.com/insidejvm/ed2/threadsynchP.html

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.