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
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();
}
The major difference is to wait to release the lock or monitor while sleep doesn't release any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution.
30 回答
wait()
在同步方法中给出,而sleep()
在非同步方法中给出,因为wait()
方法释放对象的锁定但sleep()
或yield()
确实释放了lock()
.这些方法用于不同的事情 .
Thread.sleep(n)可以被中断,但必须通知Object.wait() . 可以指定等待的最长时间:
Object.wait(5000)
所以可以使用wait
来,呃,sleep
但是你必须打扰锁 .这两种方法在睡眠/等待时都不使用cpu .
这些方法使用本机代码实现,使用类似的结构,但不是以相同的方式 .
找你自己:Is the source code of native methods available?文件
/src/share/vm/prims/jvm.cpp
是起点......关于睡眠的示例不会释放锁定并等待
这里有两个类:
Main :包含main方法和两个线程 .
Singleton :这是具有两个静态方法getInstance()和getInstance(boolean isWait)的单例类 .
和
现在运行此示例,您将获得以下输出:
这里由threadA和threadB创建的Singleton实例是相同的 . 这意味着threadB在外面等待,直到threadA释放它的锁定 .
现在通过注释Thread.sleep(500)来更改Singleton.java;方法和取消注释Singleton.class.wait(500); . 这是因为Singleton.class.wait(500);方法threadA将释放所有获取锁并进入“Non Runnable”状态,threadB将进入更改以进入synchronized块 .
现在又跑了:
这里由threadA和threadB创建的Singleton实例不相同,因为threadB得到更改以在synchronized块中输入,并且在500毫秒后threadA从它的最后位置开始并再创建一个Singleton对象 .
sleep() 是一个方法,用于将进程保持几秒或你想要的时间但是在wait()方法的情况下,线程进入等待状态,并且在我们调用notify()或notifyAll之前它不会自动返回( ) .
major difference 是 wait() 释放锁或监视器,而sleep()在等待时不释放任何锁或监视器 . 等待用于线程间通信,而睡眠通常用于在执行时引入暂停 .
Thread.sleep() 将当前线程发送到“Not Runnable”状态一段时间 . 线程保持它已获取的监视器 - 即,如果线程当前处于同步块或方法中,则其他线程不能进入该块或方法 . 如果另一个线程调用t.interrupt(),它将唤醒睡眠线程 . 请注意,sleep是一种静态方法,这意味着它总是会影响当前线程(正在执行sleep方法的线程) . 一个常见的错误是调用t.sleep(),其中t是一个不同的线程;即使这样,它是当前线程将睡眠,而不是t线程 .
object.wait() 将当前线程发送到“Not Runnable”状态,如sleep(),但有一个扭曲 . 在对象上调用Wait,而不是线程;我们将此对象称为“锁定对象” . 在调用lock.wait()之前,当前线程必须在锁定对象上进行同步; wait()然后释放此锁,并将线程添加到与锁相关联的“等待列表” . 稍后,另一个线程可以在同一个锁对象上同步并调用lock.notify() . 这唤醒了原始的等待线程 . 基本上,wait()/ notify()就像sleep()/ interrupt(),只有活动线程不需要直接指向休眠线程的指针,而只需要共享锁对象 .
让我们对以上几点进行分类:
Call on:
wait(): 呼唤一个物体;当前线程必须在锁定对象上同步 .
sleep(): 呼叫线程;总是当前正在执行线程
Synchronized:
wait(): 当同步多个线程逐个访问同一个Object时 .
sleep(): 当同步的多个线程等待睡眠线程的睡眠时 .
Hold lock:
wait(): 释放锁定以使其他对象有机会执行 .
sleep(): 如果指定超时或有人中断,则保持锁定至少t次 .
Wake-up condition:
wait(): 直到从对象调用notify(),notifyAll()
sleep(): 直到至少时间到期或调用中断() .
Usage:
sleep(): 用于时间同步和;
wait(): 用于多线程同步 .
参考:diff sleep and wait
睡眠/中断和等待/通知之间的一个潜在的巨大差异是
在sleep()期间
在wait()期间
在不需要时生成异常是低效的 . 如果你有高速率的线程相互通信,那么如果你有的话会产生很多例外一直调用中断,这完全是浪费CPU .
这里有很多答案,但我找不到任何提到的语义区别 .
这不是线程本身;这两种方法都是必需的,因为它们支持非常不同的用例 .
sleep()
将线程发送到以前的状态,它只是打包上下文并停止执行预定义的时间 . 因此,为了在到期时间之前将其唤醒,您需要知道Thread引用 . 这在多线程环境中不常见 . 它主要用于时间同步(例如,在3.5秒内唤醒)和/或硬编码公平性(只是休眠一段时间,让其他线程工作) .相反,
wait()
是一种线程(或消息)同步机制,允许您通知一个您没有存储引用的线程(也不关心) . 您可以将其视为发布 - 订阅模式(wait
== subscribe和notify()
== publish) . 基本上使用notify()你正在发送一条消息(甚至可能根本没有收到消息,通常你也不在乎) .总而言之,通常使用
sleep()
进行时间同步,使用wait()
进行多线程同步 .它们可以在底层操作系统中以相同的方式实现,或者根本不实现(因为以前版本的Java没有真正的多线程;可能一些小型虚拟机也没有这样做) . 不要忘记在VM上运行Java,因此您的代码将根据其运行的VM / OS / HW进行不同的转换 .
始终从同步块调用 Should be called from synchronized block :
wait()
方法,即wait()
方法需要在调用它的对象之前锁定对象监视器 . 但是sleep()
方法可以从外部同步块调用,即sleep()
方法不需要任何对象监视器 .IllegalMonitorStateException : 如果在没有获取对象锁的情况下调用
wait()
方法,则在运行时抛出IllegalMonitorStateException
,但sleep()
方法永远不会抛出此类异常 .Belongs to which class :
wait()
方法属于java.lang.Object
类,但sleep()
方法属于java.lang.Thread
类 .在对象上调用 Called on object or thread :
wait()
方法,但在线程而非对象上调用sleep()
方法 .Thread state : 在对象上调用
wait()
方法时,持有对象监视器的线程从运行状态变为等待状态,并且只有在该对象上调用notify()
或notifyAll()
方法时才能返回runnable状态 . 后来的线程调度程序调度该线程从可运行状态变为运行状态 . 当在线程上调用sleep()
时,它会从运行状态进入等待状态,并且当休眠时间结束时可以返回到可运行状态 .When called from synchronized block : 当调用
wait()
方法时,线程会离开对象锁 . 但是,从同步块或方法线程调用时sleep()
方法不会留下对象锁定 .更多Reference
在这里,我列出了
wait()
和sleep()
方法之间的一些重要区别 .PS: 同时点击链接查看图书馆代码(内部工作,只需稍微玩一下以便更好地理解) .
wait()
wait()
方法释放锁 .wait()
是Object
类的方法 .wait()
是非静态方法 -public final void wait() throws InterruptedException { //...}
应通过
notify()
或notifyAll()
方法通知wait()
.需要从循环中调用
wait()
方法以处理误报 .必须从同步上下文(即同步方法或块)调用
wait()
方法,否则将抛出IllegalMonitorStateException
sleep()
sleep()
方法不释放锁 .sleep()
是java.lang.Thread
类的方法 .sleep()
是静态方法 -public static void sleep(long millis, int nanos) throws InterruptedException { //... }
在指定的时间后,
sleep()
完成 .sleep()
最好不要从循环中调用(即参见下面的代码) .可以从任何地方调用
sleep()
. 没有具体要求 .参考:Difference between Wait and Sleep
Code snippet for calling wait and sleep method
wait()
是Object
类的方法 .sleep()
是Thread
类的方法 .sleep()
允许线程进入sleep
状态x毫秒 .当一个线程进入睡眠状态
it doesn’t release the lock
.wait()
允许线程释放锁和goes to suspended state
.当为同一对象调用
notify()
或notifAll()
方法时,此线程将处于活动状态 .wait
和sleep
方法非常不同:sleep无法"waking-up",
而wait在等待期间有"waking-up"的方式,由另一个调用notify或notifyAll的线程 .
想想看,这个名字在这方面令人困惑;但
sleep
是标准名称,wait
与Win API中的WaitForSingleObject或WaitForMultipleObjects类似 .简单来说,wait is wait直到某个其他线程调用你,而sleep在某段指定的时间内“不执行next statement” .
而且,sleep是Thread类中的静态方法在线程上运行,而wait()在Object类中并在对象上调用 .
另一点,当你在某个对象上调用wait时,涉及的线程会同步对象然后等待 . :)
从这篇文章:http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/
wait()方法 .
1)调用wait()方法的线程释放它所持有的锁 .
2)在其他线程调用同一个锁上的notify()或notifyAll()方法后,线程重新获得锁定 .
3)必须在synchronized块内调用wait()方法 .
4)始终在对象上调用wait()方法 .
5)通过调用notify()或notifyAll()方法,其他线程可以唤醒等待线程 .
6)要调用wait()方法,线程必须有对象锁 .
sleep()方法
1)调用sleep()方法的线程不会释放它所持有的锁 .
2)sleep()方法可以在synchronized块内外调用 .
3)总是在线程上调用sleep()方法 .
4)其他线程无法唤醒睡眠线程 . 如果这样做,线程将抛出InterruptedException .
5)要调用sleep()方法,线程不需要具有对象锁定 .
wait可以是另一个在监视器上调用notify的线程"woken up"正在等待,而sleep则不能 .
wait
(和notify
)必须发生在监视器对象上的块synchronized
中,而sleep
不会:此时,当前正在执行的线程等待并释放监视器 . 另一个线程可能会做
(在相同的
mon
对象上)和第一个线程(假设它是在监视器上等待的唯一线程)将被唤醒 .如果监视器上有多个线程正在等待,您也可以调用notifyAll - 这将唤醒所有线程 . 但是,只有一个线程能够 grab 监视器(记住
wait
在synchronized
块中)并继续 - 其他线程将被阻塞,直到它们可以获取监视器的锁定 .另一点是你在Object上调用
wait
(即你在对象的监视器上等待),而你在Thread上调用sleep
.还有一点是你可以从
wait
获得虚假的唤醒(即等待恢复的线程没有明显的原因) . 你应该 always wait whilst spinning on some condition 如下:它导致当前正在执行的线程休眠特定的时间 .
其准确性取决于系统计时器和调度程序 .
它保留已获取的监视器,因此如果从同步上下文调用它,则没有其他线程可以进入该块或方法 .
如果我们调用interrupt()方法,它将唤醒睡眠线程 .
它导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法
必须从同步上下文中调用,即从块或方法调用 . 这意味着在调用wait()方法之前,当前线程必须锁定该对象 .
它在调用它的对象上释放锁定并添加到等待列表中,因此另一个线程可以获取对象的锁定 .
sleep
是Thread
的方法,wait
是Object
的方法,因此wait/notify
是一种在Java中同步共享数据的技术(使用monitor),但sleep
是一种简单的线程暂停方法 .尚未提到的一个关键区别是,在休眠线程时不会释放它所持有的锁定,而等待时会释放对调用
wait()
的对象的锁定 .在我看来,两种机制之间的主要区别在于睡眠/中断是处理线程的最基本方式,而 wait/notify is an abstraction aimed to do thread inter-communication easier. 这意味着睡眠/中断可以做任何事情,但这个特定任务更难做到 .
为什么等待/通知更合适?以下是一些个人考虑因素:
It enforces centralization. 它允许协调一组线程与单个共享对象之间的通信 . 这大大简化了工作 .
It enforces synchronization. 因为它使程序员在同步块中包含对wait / notify的调用 .
It's independent of the thread origin and number. 使用此方法,您可以任意添加更多线程,而无需编辑其他线程或跟踪现有线程 . 如果您使用了sleep / interrupt,首先需要保留对休眠线程的引用,然后手动逐个中断它们 .
现实生活中的一个例子很好地解释了这是一个经典的餐厅和人员用来与他们沟通的方法:服务员将客户的要求留在中央位置(软木板, table 等),敲响了钟声,来自厨房的 Worker 们来接受这样的要求 . 一旦有任何课程准备好,厨房人员再次响铃,以便服务员知道并将它们带给顾客 .
等待和睡眠是两回事:
在
sleep()
中,线程停止工作指定的持续时间 .在
wait()
中,线程停止工作,直到通知其他线程通知等待的对象 .在完成等待和睡眠之后,我总结了一些不同的关键注释,首先使用wait()和sleep()查看示例:
Example1 :使用 wait ()和 sleep ():
让清晰一些关键的笔记:
Call on :
wait():调用持有HandObject Object的当前线程
sleep():调用线程执行任务获取啤酒(类方法对当前运行的线程有影响)
Synchronized :
wait():当同步多线程访问同一个Object(HandObject)时(需要在多个线程之间进行通信(线程执行编码,线程执行获取啤酒)访问同一个对象HandObject)
sleep():当等待条件继续执行时(等待啤酒可用)
Hold lock :
wait():释放其他对象的锁有机会执行(HandObject是免费的,你可以做其他工作)
sleep():保持锁定至少t次(或直到中断)(我的工作仍未完成,我继续保持锁定并等待某些条件继续)
Wake-up condition :
wait():直到从对象调用notify(),notifyAll()
sleep():直到至少时间到期或调用中断
最后一点是 use when ,因为estani表示:
如果我错了,请纠正我 .
我发现this post很有帮助 . 它将
Thread.sleep()
,Thread.yield()
和Object.wait()
之间的差异用于人类术语 . 报价:wait
释放锁定而sleep
则不释放 . 只要notify
或notifyAll
被调用,处于等待状态的线程就有资格唤醒 . 但是在sleep
的情况下,线程会保持锁定,并且只有在睡眠时间结束后它才有资格 .的根本区别在于
wait()
来自Object
而sleep()
是Thread
的静态方法 .主要区别在于
wait()
释放锁定,而sleep()
在等待时不释放任何锁定 .wait()
用于线程间通信,而sleep()
用于在执行时引入暂停 .wait()
应该从内部同步调用,否则我们得到IllegalMonitorStateException
而sleep()
可以在任何地方调用 .要从
wait()
再次启动线程,您必须调用notify()
或notifyAll()
. 在sleep(),
线程中,在指定的ms / sec间隔后启动 .两者都使当前线程进入 Not Runnable 状态 .
两者都是
native
方法 .这里wait()将处于等待状态,直到它被另一个线程通知但是sleep()将在哪里有一些时间......之后它会自动转移到Ready状态......
等待()和睡眠()差异?
Thread.sleep()一旦完成它的工作,那么只有它释放锁定给每个人 . 直到它从未向任何人发布锁定 .
Object.wait()当它进入等待阶段时,它将释放密钥并根据参数等待一些秒 .
例如:
你是右手取咖啡,你可以带另一只手拿着咖啡,你什么时候放下来然后只取另一个同样的东西在此输入 . 也 . 这是睡觉()你睡觉的时候你没有任何工作,你只是在睡觉..这里也一样 .
等待() . 当你在等待的时候放下你的另一个意思,那就等了
你是在播放电影或者你的系统中的任何东西都是一样的播放器,你不能一次播放多个,这就是它在这里,当你关闭并选择另一个电影或歌曲时,叫做等待
从
Object
Object
方法的oracle文档页面:使当前线程等待,直到另一个线程为此对象调用
notify()
方法或notifyAll()
方法 . 换句话说,此方法的行为就像它只是执行调用wait(0)
一样 .当前线程必须拥有此对象's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object'的监视器才能唤醒
中断和虚假唤醒是可能的
此方法只应由作为此对象监视器所有者的线程调用
抛出此方法
IllegalMonitorStateException
- 如果当前线程不是对象监视器的所有者 .InterruptedException
- 如果任何线程在当前线程等待通知之前或期间中断当前线程 . 抛出此异常时,将清除当前线程的中断状态 .来自o33文档页面sleep()
Thread
类的方法:使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统定时器和调度程序的精度和准确性 .
线程不会丢失任何监视器的所有权 .
此方法抛出:
IllegalArgumentException
- 如果millis的值为负数InterruptedException
- 如果有任何线程中断了当前线程 . 抛出此异常时,将清除当前线程的中断状态 .其他关键区别:
与静态方法
sleep()
(类方法)不同,wait()
是非静态方法(实例方法) .你是对的 - Sleep()导致该线程“休眠”并且CPU将关闭并处理其他线程(也称为上下文切换),我相信Wait会让CPU处理当前线程 .
我们都有两个,因为虽然让你的其他人在不使用它时使用CPU似乎是明智的,但实际上有一个上下文切换的开销 - 取决于睡眠的时间长短,它在CPU周期中会更昂贵切换线程比让你的线程在几毫秒内无所事事 .
另请注意,sleep强制进行上下文切换 .
此外 - 通常不可能控制上下文切换 - 在等待操作系统可能(并且将持续更长时间等待)期间选择处理其他线程 .
这是一个非常简单的问题,因为这两种方法都有完全不同的用法 .
The major difference is to wait to release the lock or monitor while sleep doesn't release any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution.
这只是一个清晰而基本的解释,如果你想要更多,那么继续阅读 .
如果
wait()
方法线程进入等待状态,它将不会自动返回,直到我们调用notify()
方法(或notifyAll()
如果你有多个线程处于等待状态并且你想要唤醒所有这些线程) . 并且您需要同步或对象锁或类锁来访问wait()
或notify()
或notifyAll()
方法 . 还有一件事,wait()
方法用于线程间通信,因为如果线程进入等待状态,您将需要另一个线程来唤醒该线程 .但是在
sleep()
的情况下,这是一种方法,用于将过程保持几秒钟或您想要的时间 . 因为您不需要激发任何notify()
或notifyAll()
方法来获取该线程 . 或者你不希望用户等到计算机播放然后你可以提到sleep()
方法 .还有一个在访谈中经常被问到的重要区别:
sleep()
属于Thread
类,wait()
属于Object
类 .这些是
sleep()
和wait()
之间的所有差异 .并且两种方法之间存在相似性:它们都是检查语句,因此您需要尝试catch或throws来访问这些方法 .
我希望这能帮到您 .
sleep()
方法导致当前线程在指定时间内从运行状态移动到块状态 . 如果当前线程具有任何对象的锁定,则它继续保持它,这意味着其他线程无法在该类对象中执行任何同步方法 .wait()
方法导致当前线程在指定时间内或直到通知进入阻塞状态,但在这种情况下,线程释放对象的锁(这意味着其他线程可以执行调用对象的任何同步方法 .等待超时值可以在超时值超时后唤醒或通知较早者(或中断),而睡眠时间超过超时值时唤醒或中断较早者 . 没有超时值的wait()将等待直到通知或中断
来源:http://www.jguru.com/faq/view.jsp?EID=47127