wait()和sleep()之间的区别

线程中的wait()sleep()有什么区别?

我的理解是一个wait()线程仍处于运行模式,并使用CPU周期,但sleep()不消耗任何CPU周期正确?

为什么我们有wait()sleep() :它们的实现在较低的层次上是如何变化的?

一个wait可以被另一个线程唤醒,这个线程在正在等待的监视器上调用notify ,而sleep则不能。 在监视器对象上synchronized的块中也必须wait (而且notify ),而sleep不会:

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

此时当前正在执行的线程等待并释放监视器 。 另一个线程可能会做

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

(在同一个mon对象上),第一个线程(假设它是在显示器上等待的唯一线程)将会唤醒。

如果监视器上有多个线程正在等待,您也可以调用notifyAll – 这将唤醒所有的线程。 但是,只有一个线程能够抓取显示器(记住wait是在一个synchronized块中)并继续 – 其他的将被阻塞,直到它们能够获取显示器的锁。

另一点是,你调用Object本身的wait (即你等待一个对象的显示器),而你调用sleep Thread

还有一点是,你可以从wait得到虚假的唤醒(即,正在等待的线程无故明显地恢复)。 在一些情况下 ,您应该一直wait如下所示:

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

还没有提到的一个关键区别是,在hibernate时,线程不释放它所持有的锁,在等待释放时wait()对象的锁被调用。

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

我发现这个链接有用(引用这个职位 )。 它把人类的sleep()wait()yield()之间的区别。 (万一这些链接已经死掉了,我已经把这个postjoin了附加的标记)

这一切最终都会进入操作系统的调度程序,调度程序会向进程和线程提交时间片。

sleep(n)说: “我已经完成了我的时间片,请不要给我另外一个时间至lessn毫秒。”操作系统甚至没有尝试安排睡眠线程,直到请求的时间已经过去。

yield()表示“我已经完成了我的时间片,但是我仍然有工作要做” 。操作系统可以自由地立即给线程另外一个时间片,或者给一些其他的线程或者处理CPU,让出的线程放弃。

.wait()说: “我已经完成了我的时间片。 不要再给我另一个时间片,直到有人调用notify()。“sleep() ,操作系统甚至不会尝试调度任务,除非有人调用notify() (或者其他几个唤醒场景之一)。

当线程执行阻塞IO并在其他一些情况下,线程也会丢失时间片的剩余部分。 如果一个线程在整个时间片上运行,那么操作系统就会像调用yield()一样强行进行控制,以便其他进程可以运行。

你很less需要yield() ,但是如果你有一个具有逻辑任务边界的计算量大的应用程序,那么插入一个yield() 可能会提高系统的响应能力(以时间为代价 – 上下文切换,即使是操作系统, t免费)。 像往常一样,针对您关心的目标进行衡量和testing。

这里有很多答案,但我找不到任何提及的语义区别。

这不是关于线程本身; 这两种方法都是必需的,因为它们支持非常不同的用例。

sleep()将线程发送到睡眠状态,它只是打包上下文,并停止执行预定义的时间。 所以为了在到期之前把它唤醒,你需要知道线程引用。 这在multithreading环境中并不常见。 它主要用于时间同步(例如正好3.5秒唤醒)和/或硬编码的公平性(只是睡一会儿,让其他线程工作)。

相反, wait()是一个线程(或消息)同步机制,允许你通知一个你没有存储引用(也不在乎)的线程。 你可以把它看作一个发布 – 订阅模式( wait == subscribe and notify() == publish)。 基本上使用通知()你正在发送一个消息(甚至可能根本不会被接收,通常你不在乎)。

总之,通常使用sleep()进行时间同步, wait()进行multithreading同步。

它们可以在底层操作系统中以相同的方式实现,或者根本不实现(因为以前的Java版本没有真正的multithreading;可能有些小型的虚拟机也不这样做)。 不要忘了Java在虚拟机上运行,​​所以你的代码将根据运行的虚拟机/操作系统/硬件的不同而变化。

有一些不同的关键笔记,我等待和睡眠的工作结束后,首先看看使用wait()和sleep()的示例:

例1 :使用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():调用Thread执行任务get beer(是类方法,所以影响当前正在运行的线程)
  2. 同步
    • wait():当同步的multithreading访问同一个对象(HandObject)(当需要多个线程之间的通信(线程执行编码,线程执行get啤酒)
    • 睡觉():等待条件继续执行(等待啤酒可用)
  3. 保持locking
    • wait():释放其他对象的锁有机会执行(HandObject是免费的,你可以做其他工作)
    • 睡觉():保持locking至lesst次(或直到中断)(我的工作还没有完成,我继续保持locking,等待一些条件继续)
  4. 唤醒条件
    • wait():直到从对象中调用notify(),notifyAll()
    • 睡眠():直到至less有时间到期或呼叫中断
  5. 最后一点是 estani指出:

您通常使用sleep()进行时间同步,wait()进行multithreading同步。

如果我错了,请纠正我。

wait()sleep()方法之间有一些重要的区别。

等待()

  1. wait()方法释放锁。
  2. wait()Object类的方法。
  3. wait()是非静态方法 – public final void wait() throws InterruptedException { //...}
  4. wait()应该通过notify()notifyAll()方法来通知。
  5. wait()方法需要从循环中调用以处理虚警。

  6. wait()方法必须从同步上下文(即synchronized方法或块)中IllegalMonitorStateException ,否则会抛出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 } 

线程转换到不同的线程状态

wait()和sleep()之间的区别

  • 基本的区别是wait()来自Objectsleep()Thread静态方法。

  • 主要区别在于wait()释放锁,而sleep()在等待时不释放任何锁。

  • wait()用于进行线程间通信,而sleep()通常用于暂停执行。

  • wait()应该从内部同步调用,否则我们会得到IllegalMonitorStateExceptionsleep()可以在任何地方调用。

  • 要从wait()再次启动线程,必须调用notify()notifyAll() 。 在sleep(),线程在指定的ms / sec间隔后启动。

有助于理解的相似之处

  • 两者都使当前线程进入Not Runnable状态。
  • 两者都是native方法。

这是一个非常简单的问题,因为这两种方法的用法完全不同。

主要区别是等待释放锁或监视器,而睡眠不释放任何锁或监视器在等待。 Wait用于线程间通信,而睡眠用于暂停执行。

这只是一个清楚而基本的解释,如果你想要比那更多的话继续阅读。

wait()方法的情况下,线程进入等待状态,直到我们调用notify()方法(或者notifyAll()如果你有多个处于等待状态的线程并且你想要唤醒所有的那些线程)。 而且您需要同步或locking对象或使用类锁来访问wait()notify()notifyAll()方法。 还有一件事, wait()方法用于线程间通信,因为如果线程进入等待状态,则需要另一个线程来唤醒该线程。

但是在sleep()情况下,这是一个用来保存这个进程几秒或者你想要的时间的方法。 因为您不需要激发任何notify()notifyAll()方法来返回该线程。 或者你不需要任何其他线程callback该线程。 就像如果你希望在用户轮到你之后的几秒钟之后发生什么事情,你希望用户等待,直到电脑出现,你可以提到sleep()方法。

而在面试中经常被问到的一个更重要的区别是: sleep()属于Thread类, wait()属于Object类。

这些都是sleep()wait()之间的区别。

两种方法之间有一个相似之处:它们都是检查语句,所以你需要尝试catch或抛出来访问这些方法。

我希望这会帮助你。

来源: http : //www.jguru.com/faq/view.jsp?EID=47127

Thread.sleep()将当前线程发送到“Not Runnable”状态一段时间。 线程保持已经获得的监视器 – 也就是说,如果线程当前处于同步块或方法中,则其他线程不能进入该块或方法。 如果另一个线程调用t.interrupt() ,它将唤醒睡眠线程。

请注意,sleep是一个静态方法,这意味着它总是影响当前线程(执行睡眠方法的线程)。 一个常见的错误是调用t.sleep() ,其中t是不同的线程; 即使这样,现在的线程也会睡眠,而不是线程。

t.suspend()已被弃用。 使用它可以停止当前线程以外的线程。 挂起的线程保留所有的监视器,并且由于这个状态不可中断,所以容易出现死锁。

object.wait()将当前线程发送到“Not Runnable”状态,如sleep() ,但带有扭曲。 等待被调用的对象,而不是一个线程; 我们称这个对象为“locking对象”。 在lock.wait()之前,当前线程必须在锁对象上同步; wait()然后释放这个锁,并将该线程添加到与该锁关联的“等待列表”中。 稍后,另一个线程可以在同一个锁对象上同步并调用lock.notify() 。 这唤醒了原来的等待线程。 基本上, wait() / notify()就像sleep() / interrupt() ,只有活动线程不需要直接指向睡眠线程的指针,而只需要共享锁对象。

等待和睡眠是两回事:

  • sleep() ,线程在指定的持续时间内停止工作。
  • wait() ,线程停止工作,直到被通知的对象通常由其他线程通知。

sleepThread一种方法, waitObject一个方法,所以wait/notify是一种同步Java中共享数据的技术(使用monitor ),而sleep是一个简单的线程暂停方法。

sleep()是一个用来保存进程几秒钟或者你想要的时间的方法,但是在wait()方法的时候线程进入等待状态,直到我们调用notify()或者notifyAll的()。

主要区别在于wait()释放锁或监视器,而sleep()在等待期间不释放任何锁或监视器。 一般来说,等待用于线程间通信,而睡眠用于暂停执行。

Thread.sleep()将当前线程发送到“Not Runnable”状态一段时间。 线程保留它已经获得的监视器 – 即,如果线程当前处于同步块或方法中,则其他线程不能进入该块或方法。 如果另一个线程调用t.interrupt(),它将唤醒睡眠线程。 请注意,sleep是一个静态方法,这意味着它总是影响当前线程(执行睡眠方法的线程)。 一个常见的错误是调用t.sleep(),其中t是不同的线程; 即使这样,现在的线程也会睡眠,而不是线程。

object.wait()将当前线程发送到“Not Runnable”状态,如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():当同步时,多个线程等待睡眠线程的hibernate。

Hold lock:

  • wait():释放其他对象的locking以便有机会执行。
  • sleep():如果超时指定或某人中断,则保持locking至lesst次。

Wake-up condition:

  • wait():直到从对象中调用notify(),notifyAll()
  • sleep():直到至less时间到期或者调用interrupt()。

Usage:

  • 睡眠():用于时间同步;
  • wait():用于multithreading同步。

参考: 差异sleepwait

waitsleep方法是非常不同的:

  • sleep没有办法“醒来”,
  • wait在等待期间有一种叫醒或notifyAll

想想看,名字在这方面是混淆的; 然而, sleep是一个标准名称, wait就像Win API中的WaitForSingleObjectWaitForMultipleObjects

简单地说,等待是等待直到其他线程调用你,而睡眠是“不执行下一个语句”一段指定的时间。

而且sleep是Thread类中的静态方法,它在线程上运行,而wait()在Object类中并在一个对象上调用。

还有一点,当你调用某个对象的等待时,涉及到的线程会同步该对象,然后等待。 🙂

从这篇文章: 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()方法,线程必须有对象locking。

睡眠()方法

1)调用sleep()方法的线程不释放它保存的锁。

2)sleep()方法可以在synchronized块内部或外部调用。

3)sleep()方法总是在线程上调用。

4)睡眠线程不能被其他线程唤醒。 如果这样做,线程将抛出InterruptedException。

5)要调用sleep()方法,线程不需要有对象locking。

睡觉

  • 它导致当前正在执行的线程hibernate特定的时间量。
  • 其准确性取决于系统定时器和调度程序。
  • 它保留已经获得的监视器,所以如果从同步上下文中调用它,则其他线程不能进入该块或方法。
  • 如果我们调用interrupt()方法,它会唤醒睡眠线程。

等待

  • 它导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法
  • 它必须从同步的上下文中调用,即从块或方法中调用。它意味着在调用wait()方法之前,当前线程必须locking该对象。
  • 它释放对它所调用的对象的锁,并将其添加到等待列表中,以便另一个线程可以获取该对象上的锁。
  1. wait()Object类的一个方法。
    sleep()Thread类的一个方法。

  2. sleep()允许线程进入sleep状态x毫秒。
    当线程进入睡眠状态时, it doesn't release the lock

  3. wait()允许线程释放locking并goes to suspended state
    对同一个对象调用notify()notifAll()方法时,此线程将处于活动状态。

睡眠/中断和等待/通知之间的一个潜在的巨大差异是

  • sleep() interrupt()期间调用interrupt()总是抛出exception(例如InterruptedException ),而
  • wait() notify()期间调用notify()不会。

在不需要时生成exception是低效的。 如果你的线程以较高的速度进行通信,那么如果你一直在调用中断,就会产生很多的exception,这完全是CPU的浪费。

你是正确的 – 睡眠()导致线程“睡眠”和CPU将closures和处理其他线程(否则称为上下文切换)我认为等待保持CPU处理当前线程。

我们都有,因为尽pipe在不使用CPU的时候让其他人使用CPU似乎是明智的做法,但实际上,上下文切换有一个开销 – 取决于睡眠的时间长短,CPU周期可能会更加昂贵切换线程比简单地让你的线程几毫秒无所事事。

另请注意,睡眠强制上下文切换。

另外 – 一般来说,不可能控制上下文切换 – 在等待操作系统可能(并将等待更长的时间)select处理其他线程。

这些方法被用于不同的事情。

 Thread.sleep(5000); // Wait until the time has passed. Object.wait(); // Wait until some other thread tells me to wake up. 

Thread.sleep(n) 可以被中断,但是Object.wait() 必须被通知。 可以指定等待的最长时间: 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()当它进入等待阶段时,它将释放密钥并等待一些基于参数的秒数。

例如:

你是右手拿咖啡的,你可以拿同一只手的另一个人,你什么时候放下,然后在这里只拿另外一个物体。 也。 this is sleep() you sleep time you didn't any work, you are doing only sleeping.. same here also.

wait(). when you are put down and take another one mean while you are waiting , that's wait

you are play movie or anything in yours system same as player you can't play more than one at a time right, thats its here, when you close and choose another anyone movie or song mean while is called wait

In my opinion, the main difference between both mechanisms is that sleep/interrupt is the most basic way of handling threads, whereas wait/notify is an abstraction aimed to do thread inter-communication easier. This means that sleep/interrupt can do anything, but that this specific task is harder to do.

Why is wait/notify more suitable? Here are some personal considerations:

  1. It enforces centralization. It allows to coordinate the communication between a group of threads with a single shared object. This simplifies the work a lot.

  2. It enforces synchronization. Because it makes the programmer wrap the call to wait/notify in a synchronized block.

  3. It's independent of the thread origin and number. With this approach you can add more threads arbitrarily without editing the other threads or keeping a track of the existing ones. If you used sleep/interrupt, first you would need to keep the references to the sleeping threads, and then interrupt them one by one, by hand.

An example from the real life that is good to explain this is a classic restaurant and the method that the personnel use to communicate among them: The waiters leave the customer requests in a central place (a cork board, a table, etc.), ring a bell, and the workers from the kitchen come to take such requests. Once that there is any course ready, the kitchen personnel ring the bell again so that the waiters are aware and take them to the customers.

Example about sleep doesn't release lock and wait does

Here there are two classes :

  1. Main : Contains main method and two threads.
  2. Singleton : This is singleton class with two static methods getInstance() and 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; } } 

Now run this example you will get below output :

 _instance :null Both singleton are same 

Here Singleton instances created by threadA and threadB are same. It means threadB is waiting outside until threadA release it's lock.

Now change the Singleton.java by commenting Thread.sleep(500); method and uncommenting Singleton.class.wait(500); 。 Here because of Singleton.class.wait(500); method threadA will release all acquire locks and moves into the “Non Runnable” state, threadB will get change to enter in synchronized block.

Now run again :

 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 

Here Singleton instances created by threadA and threadB are NOT same because of threadB got change to enter in synchronised block and after 500 milliseconds threadA started from it's last position and created one more Singleton object.

Should be called from synchronized block : wait() method is always called from synchronized block ie wait() method needs to lock object monitor before object on which it is called. But sleep() method can be called from outside synchronized block ie sleep() method doesn't need any object monitor.

IllegalMonitorStateException : if wait() method is called without acquiring object lock than IllegalMonitorStateException is thrown at runtime, but sleep() method never throws such exception.

Belongs to which class : wait() method belongs to java.lang.Object class but sleep() method belongs to java.lang.Thread class.

Called on object or thread : wait() method is called on objects but sleep() method is called on Threads not objects.

Thread state : when wait() method is called on object, thread that holded object's monitor goes from running to waiting state and can return to runnable state only when notify() or notifyAll() method is called on that object. And later thread scheduler schedules that thread to go from from runnable to running state. when sleep() is called on thread it goes from running to waiting state and can return to runnable state when sleep time is up.

When called from synchronized block : when wait() method is called thread leaves the object lock. But sleep() method when called from synchronized block or method thread doesn't leaves object lock.

For More Reference

From oracle documentation page on wait() method of Object :

 public final void wait() 
  1. Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0) .
  2. The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up
  3. interrupts and spurious wakeups are possible
  4. This method should only be called by a thread that is the owner of this object's monitor

这个方法抛出

  1. IllegalMonitorStateException – if the current thread is not the owner of the object's monitor.

  2. InterruptedException – if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

From oracle documentation page on sleep() method of Thread class:

 public static void sleep(long millis) 
  1. Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
  2. The thread does not lose ownership of any monitors.

This method throws:

  1. IllegalArgumentException – if the value of millis is negative

  2. InterruptedException – if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

Other key difference:

wait() is a non-static method (instance method) unlike static method sleep() (class method).

  • The method wait(1000) causes the current thread to sleep up to one second .
    • A thread could sleep less than 1 second if it receives the notify() or notifyAll() method call.
  • The call to sleep(1000) causes the current thread to sleep for exactly 1 second .
    • Also sleeping thread doesn't hold lock any resource . But waiting thread does.

wait releases the lock and sleep doesn't. A thread in waiting state is eligible for waking up as soon as notify or notifyAll is called. But in case of sleep the thread keeps the lock and it'll only be eligible once the sleep time is over.

Lets assume you are hearing songs.

As long as the current song is running, the next song wont play, ie Sleep() called by next song

If you finish the song it will stop and until you select play button(notify()) it wont play, ie wait() called by current song.

In this both cases songs going to Wait states.

wait() is given inside a synchronized method whereas sleep() is given inside a non-synchronized method because wait() method release the lock on the object but sleep() or yield() does release the lock() .