スレッド内のwait()
とsleep()
の違いは何ですか?
wait()
thingスレッドはまだ実行モードでCPUサイクルを使用していますが、sleep()
thingはCPUサイクルをまったく消費しないことを私は理解していますか?
なぜ both wait()
とsleep()
があるのですか:それらの実装は低レベルでどう変わるのでしょうか?
wait
name__ は、待機中のモニターで notify
name__ を呼び出す別のスレッドによって「起動」することができますが、 sleep
name__ は起動できません。また、wait
name__(およびnotify
name__)は、モニターオブジェクトのブロックsynchronized
name__内に出現する必要がありますが、sleep
name__は発生しません。
Object mon = ...;
synchronized (mon) {
mon.wait();
}
この時点で、現在実行中のスレッドはそしてモニターを解放しますを待ちます。他のスレッドでも可能
synchronized (mon) { mon.notify(); }
(同じmon
name__オブジェクト上で)最初のスレッド(これがモニター上で待機している唯一のスレッドであると想定した場合)が起動します。
notifyAll
name__ を呼び出して複数のスレッドがモニターを待機している場合は、これでそれらすべてが起動しますが起動されます。ただし、1つのスレッドだけがモニターを取得し(wait
name__がsynchronized
name__ブロック内にあることに注意してください)、実行を続行できます。他のスレッドは、モニターのロックを取得できるまでブロックされます。
もう1つのポイントは、 wait
name__ 自体でObject
name__を呼び出す(つまり、オブジェクトのモニターを待つ)のに対し、 sleep
name__ でThread
name__を呼び出すことです。
さらにもう1つのポイントは、wait
name__からspurious wakeupsを取得できることです(つまり、待機中のスレッドは明白な理由もなく再開します)。次のように ある条件で回転している間は常にwait
name__
synchronized {
while (!condition) { mon.wait(); }
}
まだ言及されていない重要な違いの1つは、スレッドのスリープ中に not が保持しているロックを解放し、待機中にwait()
が呼び出されているオブジェクトのロックを解放することです。
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
この投稿 有用だと思いました。 Thread.sleep()
、Thread.yield()
、およびObject.wait()
の違いを人間の言葉で表します。引用するには:
すべては最終的に、プロセスとスレッドにタイムスライスを渡すOSのスケジューラーに行き着きます。
sleep(n)
は、「タイムスライスは終了しました。少なくともnミリ秒は別のタイムスライスを与えないでください。」OSは、要求された時間が経過するまでスリープ状態のスレッドをスケジュールしようとさえしません。
yield()
は、「タイムスライスは終了しましたが、まだやるべきことがあります。」OSは、スレッドにすぐに別のタイムスライスを与えるか、または他のスレッドを与えるか、CPUを処理するだけで、放棄したスレッドを解放します。
wait()
はと言います。誰かがnotify()を呼び出すまで、別のタイムスライスを与えないでください。」sleep()
と同様に、OSは誰かがあなたのタスクをスケジュールしようとさえしません。notify()
を呼び出します(または他のいくつかのウェイクアップシナリオの1つが発生します)。また、スレッドは、IOのブロッキングを実行するとき、および他のいくつかの状況下で、タイムスライスの残りを失います。スレッドがタイムスライス全体で機能する場合、OSは
yield()
が呼び出されたかのように強制的に制御を取得し、他のプロセスを実行できるようにします。
yield()
が必要になることはめったにありませんが、論理タスク境界を持つ計算量の多いアプリがある場合、yield()
mightを挿入すると、システムの応答性が向上します(費用がかかります)時間の経過—コンテキストの切り替えは、OSだけに戻っても自由ではありません)。いつものように、気になる目標に対して測定し、テストします。
ここにはたくさんの答えがありますが、私はセマンティックの区別が述べられているのを見つけることができませんでした。
スレッド自体に関するものではありません。非常に異なるユースケースをサポートするため、両方の方法が必要です。
sleep()
は、スレッドを以前のようにスリープ状態にします。コンテキストをパックし、事前定義された時間実行を停止します。そのため、期限までにウェイクアップするには、スレッド参照を知る必要があります。これはマルチスレッド環境では一般的な状況ではありません。それは主に時間同期(例えば、ちょうど3.5秒で起きる)やハードコーディングされた公平性(しばらくの間だけスリープして他のスレッドを動作させる)に使用されます。
反対に、wait()
はスレッド(またはメッセージ)同期メカニズムで、参照が格納されていない(または気にしていない)スレッドに通知することができます。あなたはそれをpublish-subscribeパターンと考えることができます(wait
== subscribeとnotify()
== publish)。基本的にnotify()を使用してメッセージを送信しています(それはまったく受信されないかもしれませんし、通常は気にしません)。
まとめると、通常は時間同期にはsleep()
、マルチスレッド同期にはwait()
を使用します。
基盤となるOSにも同じ方法で実装することも、まったく実装することもできません(以前のバージョンのJavaには実際のマルチスレッドはありませんでした。おそらく、一部の小規模なVMでも同じことができません)。 JavaがVM上で実行されることを忘れないでください。そのため、コードは実行されるVM/OS/HWによって異なるものに変換されます。
ここでは、wait()
メソッドとsleep()
メソッドの間の重要な違いをいくつか挙げました。
PS: また、ライブラリのコードを見るためにリンクをクリックしてください(内部作業、理解を深めるためにちょっと遊んでください)
wait()
メソッドはロックを解除します。wait()
はObject
クラスのメソッドです。wait()
は非静的メソッドです - public final void wait() throws InterruptedException { //...}
wait()
はnotify()
またはnotifyAll()
メソッドによって通知されるべきです。誤警報に対処するためには、wait()
メソッドをループから呼び出す必要があります。
wait()
メソッドは同期化されたコンテキスト(すなわち同期化されたメソッドまたはブロック)から呼ばれなければなりません、そうでなければIllegalMonitorStateException
を投げます
sleep()
メソッドはロックを解除しません。sleep()
はJava.lang.Thread
クラスのメソッドです。sleep()
は静的メソッドです - public static void sleep(long millis, int nanos) throws InterruptedException { //... }
sleep()
は完了します。sleep()
はループから呼び出さない方が良いです(すなわち下記のコードを参照)。sleep()
はどこからでも呼び出すことができます。特別な要件はありません。参照: 待機と睡眠の違い
waitおよびsleepメソッドを呼び出すためのコードスニペット
synchronized(monitor){
while(condition == true){
monitor.wait() //releases monitor lock
}
Thread.sleep(100); //puts current thread on Sleep
}
いくつかの相違点があります。最初にwait()とsleep()を使ってサンプルを見てみましょう。
例1 :using wait ()および sleep ():
synchronized(HandObject) {
while(isHandFree() == false) {
/* Hand is still busy on happy coding or something else, please wait */
HandObject.wait();
}
}
/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
/* Beer is still coming, not available, Hand still hold glass to get beer,
don't release hand to perform other task */
Thread.sleep(5000);
}
/* Enjoy my beer now ^^ */
drinkBeers();
/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
HandObject.notifyAll();
}
いくつかのキーノートを明確にしましょう。
通常、時間同期にはsleep()を使用し、マルチスレッド同期にはwait()を使用します。
間違っていたら訂正してください。
基本的な違いは、wait()
はObject
からのものであり、sleep()
はThread
の静的メソッドであるということです。
主な違いは、wait()
がロックを解除するのに対し、sleep()
は待機中にロックを解除しないことです。
wait()
はスレッド間通信に使用され、sleep()
は一般に実行中に一時停止を導入するために使用されます。
wait()
は内部同期から呼び出す必要があります。そうしないとIllegalMonitorStateException
が得られますが、sleep()
はどこからでも呼び出せます。
wait()
からスレッドを再開するには、notify()
またはnotifyAll()
を呼び出す必要があります。 sleep(),
に関しては、スレッドは指定された時間間隔の後に開始されます。これは非常に単純な質問です。これらの方法は、まったく異なる用途があるからです。
主な違いは、スリープ中にロックまたはモニタの解放を待つことで、待機中にロックまたはモニタの解放は行われません。待機はスレッド間通信に使用され、スリープは実行時に一時停止を導入するために使用されます。
あなたがそれ以上を望むならば、これはただ明確で基本的な説明でした、それから読み続けてください。
wait()
メソッドの場合、スレッドは待機状態になり、notify()
メソッドを呼び出すまで自動的に戻りません(または、待機状態のスレッドが複数あり、それらすべてのスレッドを起動したい場合はnotifyAll()
)。 wait()
、notify()
、notifyAll()
の各メソッドにアクセスするには、同期ロック、オブジェクトロック、またはクラスロックが必要です。さらにもう1つ、wait()
メソッドはスレッド間通信に使用されます。スレッドが待機状態になると、そのスレッドをウェイクアップするために別のスレッドが必要になるためです。
しかしsleep()
の場合、これは数秒間またはあなたが望む時間の間プロセスを保持するために使用される方法です。スレッドを取り戻すためにnotify()
やnotifyAll()
メソッドを起動する必要がないからです。あるいは、そのスレッドをコールバックするために他のスレッドを必要としません。ユーザーの順番が終わった後のゲームのように、数秒後に何かが起こるようにしたいのなら、コンピューターが再生されるまでユーザーに待たせたいのなら、sleep()
メソッドを挙げることができます。
インタビューでよく聞かれるもう1つの重要な違いがあります。sleep()
はThread
クラスに属し、wait()
はObject
クラスに属します。
これらはsleep()
とwait()
の違いです。
そして、両方のメソッドには類似点があります。両方ともチェック済みステートメントであるため、これらのメソッドにアクセスするにはtry catchまたはthrowが必要です。
これがお役に立てば幸いです。
ソース: http://www.jguru.com/faq/view.jsp?EID=47127
Thread.sleep()
は現在のスレッドをしばらくの間 "Not Runnable" の状態にします。スレッドはそれが獲得したモニタを保持する - すなわち、スレッドが現在同期ブロックまたはメソッド内にある場合、他のスレッドはこのブロックまたはメソッドに入ることができない。他のスレッドがt.interrupt()
を呼び出すと、スリープ状態のスレッドが起動します。Sleepは静的メソッドなので、現在のスレッド(sleepメソッドを実行しているスレッド)には常に影響があります。よくある間違いは
t.sleep()
を呼び出すことです。ここでtは別のスレッドです。それでも、スリープするのは現在のスレッドであり、tスレッドではありません。
t.suspend()
は推奨されていません。現在のスレッド以外のスレッドを停止することができます。中断状態のスレッドはすべてのモニタを保持します。この状態は割り込み可能ではないため、デッドロックが発生しやすくなります。
object.wait()
は、現在のスレッドを "Not Runnable" の状態にします。ただし、sleep()
と同じですが、ひねりを加えています。待機はスレッドではなくオブジェクトに対して呼び出されます。このオブジェクトを「ロックオブジェクト」と呼びます。lock.wait()
が呼び出される前に、現在のスレッドはロックオブジェクトと同期する必要があります。wait()
はこのロックを解除し、ロックに関連付けられている「待機リスト」にスレッドを追加します。後で、別のスレッドが同じロックオブジェクトで同期してlock.notify()
を呼び出すことができます。これは元の待機スレッドを起こします。基本的に、wait()
/notify()
はsleep()
/interrupt()
に似ています。アクティブなスレッドだけがスリープ状態のスレッドへの直接ポインタを必要とせず、共有ロックオブジェクトのみを必要とします。
待機と睡眠は、2つの異なる点があります。
sleep()
では、スレッドは指定された期間動作を停止します。wait()
では、待ち状態のオブジェクトに通知があるまで、通常は他のスレッドによってスレッドが動作を停止します。sleep
はThread
のメソッド、wait
はObject
のメソッドなので、wait/notify
は( monitor を使用して)共有データを同期させる手法ですが、sleep
は自分自身を一時停止させる単純な方法です。
sleep() は、数秒間または必要な時間だけプロセスを保持するために使用されるメソッドですが、wait()メソッドの場合、スレッドは待機状態になり、自動的に戻ってくるまでは待機しません。 notify()またはnotifyAll()を呼び出します。
主な違い は、 wait() がsleep()の間にロックまたはモニタを解放し、待機中にロックまたはモニタを解放しないことです。一般に、待機はスレッド間の通信に使用され、スリープは実行時に一時停止を導入するために使用されます。
Thread.sleep() 現在のスレッドを一定時間「実行不可」状態にします。スレッドは、それが獲得したモニタを保持する - すなわち、スレッドが現在同期ブロックまたはメソッド内にある場合、他のスレッドはこのブロックまたはメソッドに入ることができない。他のスレッドがt.interrupt()を呼び出すと、スリープ状態のスレッドを起こします。 sleepは静的メソッドなので、現在のスレッド(sleepメソッドを実行しているスレッド)には常に影響があります。よくある間違いは、t.sleep()を呼び出すことです。ここで、tは別のスレッドです。それでも、スリープするのは現在のスレッドであり、tスレッドではありません。
object.wait() sleep()のように、現在のスレッドを "実行不可"状態にしますが、ひねりを加えます。待機はスレッドではなくオブジェクトに対して呼び出されます。このオブジェクトを「ロックオブジェクト」と呼びます。lock.wait()が呼び出される前に、現在のスレッドはロックオブジェクトと同期する必要があります。次にwait()はこのロックを解放し、ロックに関連付けられている「待機リスト」にスレッドを追加します。後で、別のスレッドが同じロックオブジェクトで同期してlock.notify()を呼び出すことができます。これは元の待機スレッドを起こします。基本的に、wait()/ notify()はsleep()/ interrupt()に似ています。アクティブなスレッドだけが、スリープしているスレッドへの直接のポインタを必要とせず、共有ロックオブジェクトだけを必要とします。
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
上記のすべての点を分類しましょう。
Call on:
Synchronized:
Hold lock:
Wake-up condition:
Usage:
参照: diff sleep
とwait
wait
メソッドとsleep
メソッドは大きく異なります。
考えてみると、名前はその点で混乱しています。ただし、sleep
は標準名で、wait
はWin APIの WaitForSingleObject
または WaitForMultipleObjects
のようなものです。
この投稿から: http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-Java/ /
1)wait()メソッドを呼び出したスレッドが保持しているロックを解放します。
2)他のスレッドが同じロックに対してnotify()メソッドまたはnotifyAll()メソッドを呼び出した後、スレッドはロックを回復します。
3)wait()メソッドはsynchronizedブロック内で呼び出す必要があります。
4)wait()メソッドは常にオブジェクトに対して呼び出されます。
5)notify()メソッドまたはnotifyAll()メソッドを呼び出すことで、待機中のスレッドを他のスレッドによって起こすことができます。
6)wait()メソッドを呼び出すには、スレッドにオブジェクトロックが必要です。
1)sleep()メソッドを呼び出すスレッドは、それが保持しているロックを解放しません。
2)sleep()メソッドは、同期ブロックの内部または外部で呼び出すことができます。
3)sleep()メソッドは常にスレッド上で呼び出されます。
4)他のスレッドがスリープ状態のスレッドを起こすことはできません。そうであれば、スレッドはInterruptedExceptionをスローします。
5)sleep()メソッドを呼び出すために、スレッドはオブジェクトロックを持つ必要はありません。
簡単に言うと、waitはwaitです。他のスレッドがあなたを呼び出すまで、sleepは指定された時間の間「次の文を実行しない」です。
さらに、sleepはThreadクラスの静的メソッドであり、スレッド上で動作しますが、wait()はObjectクラス内にあり、オブジェクトに対して呼び出されます。
別の点として、あるオブジェクトに対してwaitを呼び出すと、関係するスレッドはそのオブジェクトを同期してから待機します。 :)
Sleep/interruptとwait/notifyの大きな違いの1つは、
interrupt()
の呼び出し中 sleep()
は常に例外をスローします(例: InterruptedException )。notify()
の間に wait()
を呼び出すことはできません。不要なときに例外を生成するのは非効率的です。スレッド同士が高速で通信している場合、常にinterruptを呼び出すと大量の例外が発生します。これはCPUの無駄遣いです。
wait()
はObject
クラスのメソッドです。sleep()
はThread
クラスのメソッドです。
sleep()
により、スレッドはxミリ秒間sleep
状態に移行できます。
スレッドがスリープ状態に入るとit doesn’t release the lock
。
wait()
はスレッドがロックとgoes to suspended state
を解放することを可能にします。
このスレッドは、同じオブジェクトに対してnotify()
またはnotifAll()
メソッドが呼び出されるとアクティブになります。
ここでwait()は別のスレッドによって通知されるまで待機状態になりますが、sleep()はしばらく時間がかかります。その後、自動的にReady状態に移行します...
メソッドはさまざまな目的で使用されます。
Thread.sleep(5000); // Wait until the time has passed.
Object.wait(); // Wait until some other thread tells me to wake up.
Thread.sleep(n)canは中断されますが、Object.wait()mustは通知されます。最大待機時間を指定することは可能です:Object.wait(5000)
そのため、wait
をsleep
に使用することは可能ですが、その場合はロックを気にする必要があります。
どちらの方法も、スリープ/待機中にCPUを使用しません。
これらのメソッドはネイティブコードを使用して実装されています。同様のコンストラクトを使用していますが、同じ方法ではありません。
あなた自身を探してください: ネイティブメソッドのソースコードは利用可能ですか?/src/share/vm/prims/jvm.cpp
ファイルが開始点です...
Wait()とsleep()の違いは?
Thread.sleep()作業が完了すると、そのロックのみが全員にロックを解除します。それは誰にもロックを決して解放しないまで。
Sleep() take the key, its never release the key to anyone, when its work completed then only its release then only take the key waiting stage threads.
Object.wait()待機段階に入ると、キーを離し、パラメータに基づいて数秒間待機します。
例えば:
あなたはあなたのコーヒーを右手に持っています、あなたはもう片方の同じ手を取っていることができます。また。これはsleep()あなたが仕事をしていない時間を眠る、あなたは眠るだけをしている..ここでも同じです。
待つ()。あなたが据え置かれ、待っている間に別の手段をとるとき、それは待つ
あなたが映画を再生しているか、プレーヤーと同じシステム内の何かを同時に再生することはできません
wait
はロックを解放し、sleep
は解放しません。待機状態のスレッドは、notify
またはnotifyAll
が呼び出されるとすぐにウェイクアップするのに適しています。しかしsleep
の場合、スレッドはロックを保持し、スリープ時間が終了した後にのみ適格になります。
あなたは正しいです - Sleep()はそのスレッドを「スリープ」させ、CPUはオフになり、他のスレッドを処理します(コンテキスト切り替えとも呼ばれます)。
使用していないときに他の人にCPUを使用させるのが賢明に思えるかもしれませんが、実際にはコンテキストの切り替えにオーバーヘッドがあります。それは単にあなたのスレッドが数msの間何もしないようにすることよりもスレッドを切り替えることです。
また、スリープは強制的にコンテキストを切り替えます。
また、 - 一般的にはコンテキストの切り替えを制御することはできません - 待機中にOSが他のスレッドを処理することを選択する可能性があります。
私の意見では、両方のメカニズムの主な違いは、スリープ/割り込みがスレッドを処理する最も基本的な方法であるのに対し、 wait/notifyはスレッドの相互通信を容易にすることを目的とした抽象概念です。 これは、sleep/interruptが何でもできることを意味しますが、この特定のタスクはやるのが難しいということです。
待機/通知がより適しているのはなぜですか。個人的な考慮事項は次のとおりです。
集中化を強制します。 単一の共有オブジェクトを持つスレッドのグループ間の通信を調整することができます。これにより作業が大幅に簡素化されます。
同期を強制します。 それはプログラマにwait/notifyへの呼び出しを同期ブロックでラップさせるからです。
スレッドの起点と数には依存しません。 この方法では、他のスレッドを編集したり既存のスレッドを追跡することなく、任意にスレッドを追加することができます。 sleep/interruptを使用した場合は、最初にsleepしているスレッドへの参照を保持してから、それらを1つずつ手動で中断する必要があります。
これを説明するのに良い実生活からの例は、職員がそれらの間でコミュニケーションをとるために使用する古典的なレストランと方法です。ベルを鳴らすと、台所の労働者がそのような要求を受けるようになります。コースの準備が整ったら、キッチンの担当者がベルを再び鳴らして、ウェイターが気付いて顧客のところに持っていくようにします。
Oracleのドキュメントページの wait()Object
のメソッドから:
public final void wait()
notify()
メソッドまたはnotifyAll()
メソッドを呼び出すまで、現在のスレッドを待機させます。つまり、このメソッドは呼び出しwait(0)
を実行するのとまったく同じように動作します。このメソッドはスローします
IllegalMonitorStateException
- 現在のスレッドがオブジェクトのモニタの所有者ではない場合.
InterruptedException
- 現在のスレッドが通知を待つ前または待っている間に、いずれかのスレッドが現在のスレッドに割り込んだ場合この例外がスローされると、現在のスレッドの割り込みステータスがクリアされます。
Oracleのドキュメントページの sleep()Thread
クラスのメソッドから:
public static void sleep(long millis)
このメソッドはスローします:
IllegalArgumentException
- millisの値が負の場合
InterruptedException
- いずれかのスレッドが現在のスレッドに割り込んだ場合この例外がスローされると、現在のスレッドの割り込みステータスがクリアされます。
その他の主な違い
wait()
は、静的メソッドsleep()
(クラスメソッド)とは異なり、非静的メソッド(インスタンスメソッド)です。
スリープの例ではロックが解除されず、待機します
ここに2つのクラスがあります:
Singleton :これは2つの静的メソッドgetInstance()とgetInstance(boolean isWait)を持つシングルトンクラスです。
public class Main {
private static Singleton singletonA = null;
private static Singleton singletonB = null;
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread() {
@Override
public void run() {
singletonA = Singleton.getInstance(true);
}
};
Thread threadB = new Thread() {
@Override
public void run() {
singletonB = Singleton.getInstance();
while (singletonA == null) {
System.out.println("SingletonA still null");
}
if (singletonA == singletonB) {
System.out.println("Both singleton are same");
} else {
System.out.println("Both singleton are not same");
}
}
};
threadA.start();
threadB.start();
}
}
そして
public class Singleton {
private static Singleton _instance;
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
public static Singleton getInstance(boolean isWait) {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null) {
if (isWait) {
try {
// Singleton.class.wait(500);//Using wait
Thread.sleep(500);// Using Sleep
System.out.println("_instance :"
+ String.valueOf(_instance));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
_instance = new Singleton();
}
}
}
return _instance;
}
}
この例を実行すると、以下のような出力が得られます。
_instance :null
Both singleton are same
ここでthreadAとthreadBによって作成されたシングルトンインスタンスは同じです。これは、threadAがロックを解除するまでthreadBが外部で待機していることを意味します。
Thread.sleep(500)をコメントしてSingleton.Javaを変更します。メソッドおよびコメント解除Singleton.class.wait(500); 。これはSingleton.class.wait(500)のためです。メソッドthreadAはすべての獲得ロックを解放し、「Non Runnable」状態に移行し、threadBは同期ブロックに入るための変更を取得します。
もう一度実行してください。
SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same
ThreadBがsynchronizedブロックに入るように変更され、500ミリ秒後にthreadAがその最後の位置から開始し、もう1つのSingletonオブジェクトが作成されたため、threadAとthreadBによって作成されたSingletonインスタンスは同じではありません。
sleep()
メソッドは、現在のスレッドを指定された時間実行状態からブロック状態に移行させます。現在のスレッドが任意のオブジェクトのロックを保持している場合は、それを保持し続けます。つまり、他のスレッドはそのクラスオブジェクト内の同期メソッドを実行できません。
wait()
メソッドは、指定された時間またはnotifyまで現在のスレッドをブロック状態にしますが、この場合、スレッドはオブジェクトのロックを解除します(つまり、他のスレッドは呼び出し元オブジェクトの同期メソッドを実行できます)。
synchronizedブロックから呼び出す必要があります。 wait()
メソッドは常にsynchronizedブロックから呼び出されます。つまり、wait()
メソッドは、呼び出されるオブジェクトの前にオブジェクトモニターをロックする必要があります。しかし、sleep()
メソッドは外部の同期ブロックから呼び出すことができます。つまり、sleep()
メソッドはオブジェクトモニタを必要としません。
IllegalMonitorStateException: 実行時にIllegalMonitorStateException
がスローされるよりもオブジェクトロックを取得せずにwait()
メソッドが呼び出された場合、sleep()
メソッドはそのような例外をスローしません。
どのクラスに属しますか: wait()
メソッドはJava.lang.Object
クラスに属しますが、sleep()
メソッドはJava.lang.Thread
クラスに属します。
オブジェクトまたはスレッドで呼び出されます。 wait()
メソッドはオブジェクトで呼び出されますが、sleep()
メソッドはオブジェクトではなくスレッドで呼び出されます。
スレッド状態: オブジェクトのwait()
メソッドが呼び出されたとき、オブジェクトのモニタを保留していたスレッドは実行状態から待機状態になり、そのオブジェクトに対してnotify()
またはnotifyAll()
メソッドが呼び出された場合にのみ実行可能状態に戻ります。そして後で、スレッドスケジューラはそのスレッドを実行可能状態から実行状態に移行するようにスケジュールします。 sleep()
がスレッド上で呼び出されると、実行状態から待機状態になり、スリープ時間が経過すると実行可能状態に戻ることができます。
synchronizedブロックから呼び出されたとき: wait()
メソッドが呼び出されたときthreadはオブジェクトロックを解除します。しかし、同期ブロックまたはメソッドスレッドから呼び出されたsleep()
メソッドは、オブジェクトのロックを解除しません。
詳細について 参照
実際、これはすべてJavaのドキュメントに明確に記載されています(ただし、答えを読んだ後で初めてこれがわかりました)。
http://docs.Oracle.com/javase/8/docs/api/index.html :
wait() - 現在のスレッドはこのオブジェクトのモニタを所有していなければなりません。スレッドはこのモニターの所有権を解放し、notifyメソッドまたはnotifyAllメソッドへの呼び出しを介して、このオブジェクトのモニターで待機しているスレッドに別のスレッドが通知するまで待機します。その後、スレッドはモニターの所有権を取り戻すことができるようになるまで待機し、実行を再開します。
sleep() - システムタイマーとスケジューラの正確さと正確さに応じて、現在実行中のスレッドを指定されたミリ秒の間スリープ(実行を一時的に停止)させます。スレッドはモニターの所有権を失うことはありません。
wait(1000)
は、現在のスレッドを 1秒までスリープさせる 。notify()
または notifyAll()
メソッド呼び出しを受け取った場合、スレッドは1秒以内にスリープします。sleep(1000)
を呼び出すと、現在のスレッドは 正確に1秒 の間スリープします。wait()
メソッドはオブジェクトのロックを解除しますが、sleep()
またはwait()
はsleep()
を解除するため、yield()
は同期メソッド内で指定されますが、lock()
は非同期メソッド内で指定されます。
タイムアウト値で待機すると、タイムアウト値が経過したときにウェイクアップするか、早い方(または割り込み)のどちらかに通知することができます。タイムアウト値のないwait()は通知されるか中断されるまでずっと待ちます
あなたが歌を聞いていると仮定しよう。
現在の曲が実行されている限り、次の曲は再生されません。つまり、次の曲によって呼び出されたSleep()です。
曲を終了すると停止し、再生ボタンを選択する(notify())まで再生されません。つまり、wait()は現在の曲によって呼び出されます。
この両方の場合において、歌はウェイト州に行きます。