web-dev-qa-db-ja.com

待ち()とsleep()の違い

スレッド内のwait()sleep()の違いは何ですか?

wait()thingスレッドはまだ実行モードでCPUサイクルを使用していますが、sleep()thingはCPUサイクルをまったく消費しないことを私は理解していますか?

なぜ both wait()sleep()があるのですか:それらの実装は低レベルでどう変わるのでしょうか?

1123
Geek

waitname__ は、待機中のモニターで notifyname__ を呼び出す別のスレッドによって「起動」することができますが、 sleepname__ は起動できません。また、waitname__(およびnotifyname__)は、モニターオブジェクトのブロックsynchronizedname__内に出現する必要がありますが、sleepname__は発生しません。

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

この時点で、現在実行中のスレッドはそしてモニターを解放しますを待ちます。他のスレッドでも可能

synchronized (mon) { mon.notify(); }

(同じmonname__オブジェクト上で)最初のスレッド(これがモニター上で待機している唯一のスレッドであると想定した場合)が起動します。

notifyAllname__ を呼び出して複数のスレッドがモニターを待機している場合は、これでそれらすべてが起動しますが起動されます。ただし、1つのスレッドだけがモニターを取得し(waitname__がsynchronizedname__ブロック内にあることに注意してください)、実行を続行できます。他のスレッドは、モニターのロックを取得できるまでブロックされます。

もう1つのポイントは、 waitname__ 自体でObjectname__を呼び出す(つまり、オブジェクトのモニターを待つ)のに対し、 sleepname__Threadname__を呼び出すことです。

さらにもう1つのポイントは、waitname__からspurious wakeupsを取得できることです(つまり、待機中のスレッドは明白な理由もなく再開します)。次のように ある条件で回転している間は常にwaitname__

synchronized {
    while (!condition) { mon.wait(); }
}
789
oxbow_lakes

まだ言及されていない重要な違いの1つは、スレッドのスリープ中に not が保持しているロックを解放し、待機中にwait()が呼び出されているオブジェクトのロックを解放することです。

synchronized(LOCK) {
    Thread.sleep(1000); // LOCK is held
}


synchronized(LOCK) {
    LOCK.wait(); // LOCK is not held
}
311
Robert Munteanu

この投稿 有用だと思いました。 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だけに戻っても自由ではありません)。いつものように、気になる目標に対して測定し、テストします。

227
E-rich

ここにはたくさんの答えがありますが、私はセマンティックの区別が述べられているのを見つけることができませんでした。

スレッド自体に関するものではありません。非常に異なるユースケースをサポートするため、両方の方法が必要です。

sleep()は、スレッドを以前のようにスリープ状態にします。コンテキストをパックし、事前定義された時間実行を停止します。そのため、期限までにウェイクアップするには、スレッド参照を知る必要があります。これはマルチスレッド環境では一般的な状況ではありません。それは主に時間同期(例えば、ちょうど3.5秒で起きる)やハードコーディングされた公平性(しばらくの間だけスリープして他のスレッドを動作させる)に使用されます。

反対に、wait()はスレッド(またはメッセージ)同期メカニズムで、参照が格納されていない(または気にしていない)スレッドに通知することができます。あなたはそれをpublish-subscribeパターンと考えることができます(wait == subscribeとnotify() == publish)。基本的にnotify()を使用してメッセージを送信しています(それはまったく受信されないかもしれませんし、通常は気にしません)。

まとめると、通常は時間同期にはsleep()、マルチスレッド同期にはwait()を使用します。

基盤となるOSにも同じ方法で実装することも、まったく実装することもできません(以前のバージョンのJavaには実際のマルチスレッドはありませんでした。おそらく、一部の小規模なVMでも同じことができません)。 JavaがVM上で実行されることを忘れないでください。そのため、コードは実行されるVM/OS/HWによって異なるものに変換されます。

65
estani

ここでは、wait()メソッドとsleep()メソッドの間の重要な違いをいくつか挙げました。
PS: また、ライブラリのコードを見るためにリンクをクリックしてください(内部作業、理解を深めるためにちょっと遊んでください)

待つ()

  1. wait()メソッドはロックを解除します。
  2. wait()Objectクラスのメソッドです。
  3. wait()は非静的メソッドです - public final void wait() throws InterruptedException { //...}
  4. wait()notify()またはnotifyAll()メソッドによって通知されるべきです。
  5. 誤警報に対処するためには、wait()メソッドをループから呼び出す必要があります。

  6. wait()メソッドは同期化されたコンテキスト(すなわち同期化されたメソッドまたはブロック)から呼ばれなければなりません、そうでなければIllegalMonitorStateExceptionを投げます

睡眠()

  1. sleep()メソッドはロックを解除しません。
  2. sleep()Java.lang.Threadクラスのメソッドです。
  3. sleep()は静的メソッドです - public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. 指定した時間が経過すると、sleep()は完了します。
  5. sleep()はループから呼び出さない方が良いです(すなわち下記のコードを参照)。
  6. sleep()はどこからでも呼び出すことができます。特別な要件はありません。

参照: 待機と睡眠の違い

waitおよびsleepメソッドを呼び出すためのコードスニペット

synchronized(monitor){
    while(condition == true){ 
        monitor.wait()  //releases monitor lock
    }

    Thread.sleep(100); //puts current thread on Sleep    
}

thread transition to different thread states

49
roottraveller

いくつかの相違点があります。最初に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();
}

いくつかのキーノートを明確にしましょう。

  1. 電話をかける
    • wait():HandObjectオブジェクトを保持している現在のスレッドを呼び出す
    • sleep():スレッド実行タスクの実行ビール(クラスメソッドなので現在実行中のスレッドに影響する)
  2. 同期
    • wait():同期化されたマルチスレッドが同じオブジェクト(HandObject)にアクセスするとき(同じオブジェクトHandObject上で複数のスレッド(スレッド実行コーディング、スレッド実行獲得)アクセス間の通信が必要なとき)
    • sleep():実行を続けるための条件を待っているとき(利用可能なビールを待っている)
  3. ホールドロック
    • wait():他のオブジェクトのロックを解除して実行するチャンスがある(HandObjectは無料です、あなたは他の仕事をすることができます)
    • sleep():少なくともt回(または割り込みまで)ロックを保持する(私の仕事はまだ終わらない、ロックを保持し続け、続行するために何らかの条件を待っている)
  4. ウェイクアップ条件
    • wait():オブジェクトからnotify()、notifyAll()を呼び出すまで
    • sleep():少なくとも期限が切れるまで、またはinterruptを呼び出すまで
  5. そして最後のポイントは です。 as estani の場合に使用します。

通常、時間同期にはsleep()を使用し、マルチスレッド同期にはwait()を使用します。

間違っていたら訂正してください。

28
NguyenDat

Wait()とsleep()の違い

  • 基本的な違いは、wait()Objectからのものであり、sleep()Threadの静的メソッドであるということです。

  • 主な違いは、wait()がロックを解除するのに対し、sleep()は待機中にロックを解除しないことです。

  • wait()はスレッド間通信に使用され、sleep()は一般に実行中に一時停止を導入するために使用されます。

  • wait()は内部同期から呼び出す必要があります。そうしないとIllegalMonitorStateExceptionが得られますが、sleep()はどこからでも呼び出せます。

  • wait()からスレッドを再開するには、notify()またはnotifyAll()を呼び出す必要があります。 sleep(),に関しては、スレッドは指定された時間間隔の後に開始されます。

類似点

  • 両方とも現在のスレッドを Not Runnable 状態にします。
  • 両方とも native メソッドです。
22
Premraj

これは非常に単純な質問です。これらの方法は、まったく異なる用途があるからです。

主な違いは、スリープ中にロックまたはモニタの解放を待つことで、待機中にロックまたはモニタの解放は行われません。待機はスレッド間通信に使用され、スリープは実行時に一時停止を導入するために使用されます。

あなたがそれ以上を望むならば、これはただ明確で基本的な説明でした、それから読み続けてください。

wait()メソッドの場合、スレッドは待機状態になり、notify()メソッドを呼び出すまで自動的に戻りません(または、待機状態のスレッドが複数あり、それらすべてのスレッドを起動したい場合はnotifyAll())。 wait()notify()notifyAll()の各メソッドにアクセスするには、同期ロック、オブジェクトロック、またはクラスロックが必要です。さらにもう1つ、wait()メソッドはスレッド間通信に使用されます。スレッドが待機状態になると、そのスレッドをウェイクアップするために別のスレッドが必要になるためです。

しかしsleep()の場合、これは数秒間またはあなたが望む時間の間プロセスを保持するために使用される方法です。スレッドを取り戻すためにnotify()notifyAll()メソッドを起動する必要がないからです。あるいは、そのスレッドをコールバックするために他のスレッドを必要としません。ユーザーの順番が終わった後のゲームのように、数秒後に何かが起こるようにしたいのなら、コンピューターが再生されるまでユーザーに待たせたいのなら、sleep()メソッドを挙げることができます。

インタビューでよく聞かれるもう1つの重要な違いがあります。sleep()Threadクラスに属し、wait()Objectクラスに属します。

これらはsleep()wait()の違いです。

そして、両方のメソッドには類似点があります。両方ともチェック済みステートメントであるため、これらのメソッドにアクセスするにはtry catchまたはthrowが必要です。

これがお役に立てば幸いです。

18
Vikas Gupta

ソース: 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()に似ています。アクティブなスレッドだけがスリープ状態のスレッドへの直接ポインタを必要とせず、共有ロックオブジェクトのみを必要とします。

16
om singh

待機と睡眠は、2つの異なる点があります。

  • sleep()では、スレッドは指定された期間動作を停止します。
  • wait()では、待ち状態のオブジェクトに通知があるまで、通常は他のスレッドによってスレッドが動作を停止します。
14
Itay Maman

sleepThreadのメソッド、waitObjectのメソッドなので、wait/notifyは( monitor を使用して)共有データを同期させる手法ですが、sleepは自分自身を一時停止させる単純な方法です。

11
pvllnspk

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:

  • wait(): オブジェクトを呼び出す。現在のスレッドはロックオブジェクトと同期する必要があります。
  • sleep(): スレッドを呼び出す。常に現在実行中のスレッド.

Synchronized:

  • wait(): 同期された複数のスレッドが同じオブジェクトに一つずつアクセスするとき。
  • sleep(): 同期している複数のスレッドが、スリープしているスレッドのスリープオーバーを待つとき。

Hold lock:

  • wait(): 他のオブジェクトが実行する機会を得るためにロックを解除します。
  • sleep(): タイムアウトが指定された場合、または誰かが割り込みを行った場合は、少なくともt回ロックを保持します。

Wake-up condition:

  • wait(): オブジェクトからnotify()、notifyAll()を呼び出すまで
  • sleep(): 少なくとも期限が切れるまで、またはinterrupt()を呼び出す。

Usage:

  • sleep(): 時間同期のため。
  • wait(): マルチスレッド同期の場合。

参照: diff sleepwait

7
Reegan Miranda

waitメソッドとsleepメソッドは大きく異なります。

  • sleep には「目覚めさせる」方法はありません。
  • 一方、 wait は待機期間中に別のスレッドが notify または notifyAll を呼び出すことによって「起動」する方法を持っています。

考えてみると、名前はその点で混乱しています。ただし、sleepは標準名で、waitはWin APIの WaitForSingleObject または WaitForMultipleObjects のようなものです。

6
Roee Adler

この投稿から: http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-Java/ /

wait()メソッド.

1)wait()メソッドを呼び出したスレッドが保持しているロックを解放します。

2)他のスレッドが同じロックに対してnotify()メソッドまたはnotifyAll()メソッドを呼び出した後、スレッドはロックを回復します。

3)wait()メソッドはsynchronizedブロック内で呼び出す必要があります。

4)wait()メソッドは常にオブジェクトに対して呼び出されます。

5)notify()メソッドまたはnotifyAll()メソッドを呼び出すことで、待機中のスレッドを他のスレッドによって起こすことができます。

6)wait()メソッドを呼び出すには、スレッドにオブジェクトロックが必要です。

sleep()メソッド

1)sleep()メソッドを呼び出すスレッドは、それが保持しているロックを解放しません。

2)sleep()メソッドは、同期ブロックの内部または外部で呼び出すことができます。

3)sleep()メソッドは常にスレッド上で呼び出されます。

4)他のスレッドがスリープ状態のスレッドを起こすことはできません。そうであれば、スレッドはInterruptedExceptionをスローします。

5)sleep()メソッドを呼び出すために、スレッドはオブジェクトロックを持つ必要はありません。

5
user2485429

簡単に言うと、waitはwaitです。他のスレッドがあなたを呼び出すまで、sleepは指定された時間の間「次の文を実行しない」です。

さらに、sleepはThreadクラスの静的メソッドであり、スレッド上で動作しますが、wait()はObjectクラス内にあり、オブジェクトに対して呼び出されます。

別の点として、あるオブジェクトに対してwaitを呼び出すと、関係するスレッドはそのオブジェクトを同期してから待機します。 :)

5
Ratnesh Maurya

Sleep/interruptとwait/notifyの大きな違いの1つは、

不要なときに例外を生成するのは非効率的です。スレッド同士が高速で通信している場合、常にinterruptを呼び出すと大量の例外が発生します。これはCPUの無駄遣いです。

4
Mark
  1. wait()Objectクラスのメソッドです。
    sleep()Threadクラスのメソッドです。

  2. sleep()により、スレッドはxミリ秒間sleep状態に移行できます。
    スレッドがスリープ状態に入るとit doesn’t release the lock

  3. wait()はスレッドがロックとgoes to suspended stateを解放することを可能にします。
    このスレッドは、同じオブジェクトに対してnotify()またはnotifAll()メソッドが呼び出されるとアクティブになります。

4
VdeX

ここでwait()は別のスレッドによって通知されるまで待機状態になりますが、sleep()はしばらく時間がかかります。その後、自動的にReady状態に移行します...

3
Rakhi Jaligama

メソッドはさまざまな目的で使用されます。

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)そのため、waitsleepに使用することは可能ですが、その場合はロックを気にする必要があります。

どちらの方法も、スリープ/待機中にCPUを使用しません。

これらのメソッドはネイティブコードを使用して実装されています。同様のコンストラクトを使用していますが、同じ方法ではありません。

あなた自身を探してください: ネイティブメソッドのソースコードは利用可能ですか?/src/share/vm/prims/jvm.cppファイルが開始点です...

3
KarlP

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()あなたが仕事をしていない時間を眠る、あなたは眠るだけをしている..ここでも同じです。

待つ()。あなたが据え置かれ、待っている間に別の手段をとるとき、それは待つ

あなたが映画を再生しているか、プレーヤーと同じシステム内の何かを同時に再生することはできません

3
VISALIG

waitはロックを解放し、sleepは解放しません。待機状態のスレッドは、notifyまたはnotifyAllが呼び出されるとすぐにウェイクアップするのに適しています。しかしsleepの場合、スレッドはロックを保持し、スリープ時間が終了した後にのみ適格になります。

3
shikjohari

あなたは正しいです - Sleep()はそのスレッドを「スリープ」させ、CPUはオフになり、他のスレッドを処理します(コンテキスト切り替えとも呼ばれます)。

使用していないときに他の人にCPUを使用させるのが賢明に思えるかもしれませんが、実際にはコンテキストの切り替えにオーバーヘッドがあります。それは単にあなたのスレッドが数msの間何もしないようにすることよりもスレッドを切り替えることです。

また、スリープは強制的にコンテキストを切り替えます。

また、 - 一般的にはコンテキストの切り替えを制御することはできません - 待機中にOSが他のスレッドを処理することを選択する可能性があります。

3
Justin

私の意見では、両方のメカニズムの主な違いは、スリープ/割り込みがスレッドを処理する最も基本的な方法であるのに対し、 wait/notifyはスレッドの相互通信を容易にすることを目的とした抽象概念です。 これは、sleep/interruptが何でもできることを意味しますが、この特定のタスクはやるのが難しいということです。

待機/通知がより適しているのはなぜですか。個人的な考慮事項は次のとおりです。

  1. 集中化を強制します。 単一の共有オブジェクトを持つスレッドのグループ間の通信を調整することができます。これにより作業が大幅に簡素化されます。

  2. 同期を強制します。 それはプログラマにwait/notifyへの呼び出しを同期ブロックでラップさせるからです。

  3. スレッドの起点と数には依存しません。 この方法では、他のスレッドを編集したり既存のスレッドを追跡することなく、任意にスレッドを追加することができます。 sleep/interruptを使用した場合は、最初にsleepしているスレッドへの参照を保持してから、それらを1つずつ手動で中断する必要があります。

これを説明するのに良い実生活からの例は、職員がそれらの間でコミュニケーションをとるために使用する古典的なレストランと方法です。ベルを鳴らすと、台所の労働者がそのような要求を受けるようになります。コースの準備が整ったら、キッチンの担当者がベルを再び鳴らして、ウェイターが気付いて顧客のところに持っていくようにします。

2
negora

Oracleのドキュメントページの wait()Objectのメソッドから:

public final void wait()
  1. 別のスレッドがこのオブジェクトのnotify()メソッドまたはnotifyAll()メソッドを呼び出すまで、現在のスレッドを待機させます。つまり、このメソッドは呼び出しwait(0)を実行するのとまったく同じように動作します。
  2. 現在のスレッドはこのオブジェクトのモニタを所有していなければなりません。スレッドはこのモニターの所有権を解放し、このオブジェクトのモニターを待機しているスレッドに別のスレッドがウェイクアップを通知するまで待機します
  3. 割り込みや偽のウェイクアップが可能
  4. このメソッドは、このオブジェクトのモニタの所有者であるスレッドによってのみ呼び出されるべきです

このメソッドはスローします

  1. IllegalMonitorStateException - 現在のスレッドがオブジェクトのモニタの所有者ではない場合.

  2. InterruptedException - 現在のスレッドが通知を待つ前または待っている間に、いずれかのスレッドが現在のスレッドに割り込んだ場合この例外がスローされると、現在のスレッドの割り込みステータスがクリアされます。

Oracleのドキュメントページの sleep()Threadクラスのメソッドから:

public static void sleep(long millis)
  1. システムタイマーとスケジューラの正確さと正確さに応じて、現在実行中のスレッドを指定されたミリ秒の間スリープ(実行を一時的に停止)させます。
  2. スレッドはモニタの所有権を失いません。

このメソッドはスローします:

  1. IllegalArgumentException - millisの値が負の場合

  2. InterruptedException - いずれかのスレッドが現在のスレッドに割り込んだ場合この例外がスローされると、現在のスレッドの割り込みステータスがクリアされます。

その他の主な違い

wait()は、静的メソッドsleep()(クラスメソッド)とは異なり、非静的メソッド(インスタンスメソッド)です。

2
Ravindra babu

スリープの例ではロックが解除されず、待機します

ここに2つのクラスがあります:

  1. Main :mainメソッドと2つのスレッドが含まれています。
  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インスタンスは同じではありません。

2
Dhiral Pandya

sleep()メソッドは、現在のスレッドを指定された時間実行状態からブロック状態に移行させます。現在のスレッドが任意のオブジェクトのロックを保持している場合は、それを保持し続けます。つまり、他のスレッドはそのクラスオブジェクト内の同期メソッドを実行できません。

wait()メソッドは、指定された時間またはnotifyまで現在のスレッドをブロック状態にしますが、この場合、スレッドはオブジェクトのロックを解除します(つまり、他のスレッドは呼び出し元オブジェクトの同期メソッドを実行できます)。

2
User10001

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()メソッドは、オブジェクトのロックを解除しません。

詳細について 参照

2
AVI

実際、これはすべてJavaのドキュメントに明確に記載されています(ただし、答えを読んだ後で初めてこれがわかりました)。

http://docs.Oracle.com/javase/8/docs/api/index.html

wait() - 現在のスレッドはこのオブジェクトのモニタを所有していなければなりません。スレッドはこのモニターの所有権を解放し、notifyメソッドまたはnotifyAllメソッドへの呼び出しを介して、このオブジェクトのモニターで待機しているスレッドに別のスレッドが通知するまで待機します。その後、スレッドはモニターの所有権を取り戻すことができるようになるまで待機し、実行を再開します。

sleep() - システムタイマーとスケジューラの正確さと正確さに応じて、現在実行中のスレッドを指定されたミリ秒の間スリープ(実行を一時的に停止)させます。スレッドはモニターの所有権を失うことはありません。

1
TT_
  • メソッド wait(1000) は、現在のスレッドを 1秒までスリープさせる
    • スレッドがnotify() または notifyAll()メソッド呼び出しを受け取った場合、スレッドは1秒以内にスリープします。
  • sleep(1000)を呼び出すと、現在のスレッドは 正確に1秒 の間スリープします。
    • また スリープ状態のスレッドはいかなるリソースもロックしません 。しかし、待っているスレッドはそうします。
1
Rupesh

wait()メソッドはオブジェクトのロックを解除しますが、sleep()またはwait()sleep()を解除するため、yield()は同期メソッド内で指定されますが、lock()は非同期メソッド内で指定されます。

1
Aravind Mano

タイムアウト値で待機すると、タイムアウト値が経過したときにウェイクアップするか、早い方(または割り込み)のどちらかに通知することができます。タイムアウト値のないwait()は通知されるか中断されるまでずっと待ちます

1

あなたが歌を聞いていると仮定しよう。

現在の曲が実行されている限り、次の曲は再生されません。つまり、次の曲によって呼び出されたSleep()です。

曲を終了すると停止し、再生ボタンを選択する(notify())まで再生されません。つまり、wait()は現在の曲によって呼び出されます。

この両方の場合において、歌はウェイト州に行きます。

0
pavan