哪位大哥能将解一下notify()和wait()的用法 ?直接用不就得了……遇到什么问题吗?先让要等待的线程wait()……另一个线程再notify()这个线程就是啊…… 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 wait(),notify()出现与共享对象中(多个线程共享),用于暂停一个线程,在适当的时候继续线程。Both wait() and notify() must be called in synchroninzed code.下例中类Mailbox 用于实现一个共享对象,用于其他线程存储和获得消息。class Mailbox{ private boolean request; private String message; public synchronized void storeMessage(String message){ while(request == true){ try{ wait(); }catch (InterruptedException e){} } request = true; this.message = message; notify(); } public synchronized String retrieveMessage(){ while(request == false){ try{ wait(); }catch (InterruptedException e){} } request = false; notify(); return message; }} to ender:不推荐这两个方法?不会吧,这是Java 中同步的关键方法,可以说是强烈推荐要了解清楚的方法呀。 :) SORRY……把我的贴删了吧……luodi(无知者无畏)给我讲一下如何? 关于 Java 中多线程编程、线程同步可以整整写几本书,我自问没有能力三言两语说清楚,我自已也不一定清楚。:) 你的要求实在是太高了,我所能做到的只是就事论事吧。 还是没看懂呀大哥。怎么Wait()和notify()都在一个方法里?我还以为是A线程Wait, 然后B线程去notify A呢?讲讲原理好么? 不要就写一堆代码就不管了。就象上面的例子: request = false; notify(); return message;这个notify()到底在通知谁,自己还是别人呢?如果是别人,这个notify()怎么知道是该通知哪个线程?(假如我有几个线程) 我希望有解释,而不是一堆代码贴过来...... luodi(无知者无畏):能讲一个具体点的,简单的应用吗?谢谢…… foxnt(吴剑明),这个notify()是通知本线程的……你的可以这样实现:在需要wati()和notify()的线程中分别写两个同步的方法来wait()和notify(),然后在主线程中再通过另外的线程来分别调用这两个方法……具体例子见:http://www.csdn.net/expert/Topic/161/161612.shtm class Mailbox{ private boolean request; // request 如果把名字改成 isFull 会更加有说明意义,这个标志说明了信箱是不是空,是不是可以取出信。 private String message; public synchronized void storeMessage(String message){ while(request == true){ try{ wait(); // 如果信箱是满的,放弃自已对信箱获得的锁,让别的对象有机会获得这个锁,同时自已也在等待重新获得这个锁 }catch (InterruptedException e){} } request = true; // 设置信箱满的标志 this.message = message; notify(); // 通知所有等待这个锁的对象,其实此处可能用 notifyAll() 更好? } retrieveMessage() 几乎与 storeMessage() 一模一样,就不再注解了。不知这样说明行不行,有错误欢迎指出。 那个例子看过了,就是不明白才来问的啊。在WINDOW下编程,一个线程等待时,可以由另一个线程通过发送MESSAGE,从而唤醒它。而不是希望在另一个线程里通过调用该线程start()来驱动。我现在没搞清楚,在调用WAIT()时,发生了什么事情。调用NOTIFY()时,又发生了什么事情。NOTIFY()是如何去通知其他线程的?还是那句话,不要贴一堆代码,要讲原理。 谢谢luodi(无知者无畏)的讲解……明白了不少…… 调用 wait() / notify() 的前提都是已经获得了一个对象的锁,所以 wait()/notify() 都必须在 synchronized 块中调用。在已经获得了一个对象的锁的前提下,调用 wait() 会使当前线程放弃这个锁,同时通知线程调度程序,把自已放进一个等待这个锁的线程队列中去,等待再次获得这个锁。在已经获得了一个对象的锁的前提下,调用 notify() 会通知线程调度程序,唤醒其它等待这个锁的线程队列中的线程,notifyAll() 唤醒所有这类线程。核心是:要访问某个同步方法(同步在某个对象上)的类都必须先获得某个对象的锁,线程调度程序(JVM的一部分)为每一个对象锁维护一个线程队列,并把已经获得这个锁的线程调度至运行;而当一个线程失去这个锁时,就把它再度放入这个队列;当这个对象锁可以获得时,等待这个锁的线程会获得 notify(),从而让它有机会再去寻求上锁执行。 luodi(无知者无畏):在实际编程中,也许会出现尚未wait()就notify()的情况,你是如何避免这种情况出现的呢? :)不过就这个问题而言,其实要解决他的问题并不需要了解同步的知识……他只是需要能notify()一个wait()的线程而已…… 同步的东东俺知道。:)确实如ENDER所说: 只要能notify()一个wait()的线程而已…… :) notify() 通知的线程,根据 Java 的规范说明:无法预测或指定特定的线程会被执行,只是可能会执行而已。 你的问题已经解决了的啊……再给你说详细一点,假设你的两个线程:A和B在B中写一个方法来执行notify(),然后等B进入等待状态以后,A需要唤醒B时,调用B的该方法就行了……清楚了不? wait()->本线程进入等待队列,只能通过别的线程的notify()或notifyall()唤醒notify()->随机地从等待队列删除一个线程,也就是说,该线程进入执行状态notifyall()->删除所有在等待队列中的线程,按线程的优先级执行不推荐使用notify(): 因为这是随机地从等待队列中取一个线程执行,我们不能通过设定优先级进行控制,如果,随机抽取的线程不能往前执行,这就有可能产生死锁,所以,建议使用notifyall() 用 notifyAll() 后并不能确保是优先极高的线程会被执行的,因为并不能保证在特定的JVM上线程优先级会被实现,实际上,永远不能假定是哪一个线程被调度运行,详细说明可见 Java 规范。但是确实推荐notifyAll(),因为这至少让所有的等待线程有机会被执行。 也就是说,用NOTIFY()不能指定唤醒哪个线程,只是随机地唤醒队列中的某个? 我只是想激活某个线程呀。有个SOCKET的线程,收到数据后,我想通知另一个线程干活。但同时还有其他的线程,我想让他们继续睡觉。就这么简单,在WINDOW下很容易作的,在JAVA就不知道了 to foxnt(吴剑明):同步代码同一时间只能由一个线程执行,在此之前线程必须首先得到这段同步代码的锁。如果锁在另一个线程的控制之下,这个线程就会进入找锁状态,直到另一个程序释放锁。 当wait()被调用后,当前线程也会释放锁。所以就会出现一种情况: 多个线程都处于wait状态。 当条件符合时,notify()被调用,它所作的是随意从等待线程中选择一个,唤醒。记住,在java中,notify()和wait() 只能由同步代码来执行,而不是某个线程。你的socket可以参照上面的mailbox嘛 无法激活“指定”的线程。 不过你就两个线程,也就不存在“指定”的问题了。一个线程发数据,发完以后置一个标志,另一段同步代码得到这个标志就通知 另一个线程。你不用担心会通知错误,这两个线程就算都处于wait()状态,也是在不同的waiting pool中。(每一个锁都有自身的waiting pool)。 多谢各位指教,看来JAVA的东西还是不太方便。:)我换种方法吧。 关键要知道到底这个线程获得了哪些对象的锁。我是这样认为的:线程获得了synchronize作用范围内的对象的锁。如synchronized是针对某个方法,那么它获得了整个方法内所用对象的锁,所以这样用要小心。如synchronized只针对某段代码体,那么它之获得这段代码体内对象的锁,这比较容易控制。这样两个线程需同步时,可简单地选一把锁(某个对象),比如是:Object lock;Thread1 { synchronized(lock) { //获得lock …… wait(); //放弃lock,等待 …… }}Thread2 { synchronized( lock ) { //获得lock …… lock.notifyAll(); //放弃lock,通知所有等待lock的线程。 }}也就是lock,notify针对的是对象。 excel单元格换行是ALT+回车。我要写程序输出一些数据到excel,怎么实现单元格内换行? 有关String创建几个对象? 一道基础的文件写操作题 这offer给的,让我哭笑不得 接口不能实例化,能否创建引用呢? Java浮点类型 xml解析 多态内存分配问题 帮忙看一看,错在哪里? 为什么我从Oracle中longrow字段中取到本地的文件,总是乱吗呢? 小弟对Java及C#的一点看法-请大家指正! 为什么在画线的时候,自己做的鼠标光标老是闪烁?
下例中类Mailbox 用于实现一个共享对象,用于其他线程存储和获得消息。
class Mailbox{
private boolean request;
private String message;
public synchronized void storeMessage(String message){
while(request == true){
try{
wait();
}catch (InterruptedException e){}
}
request = true;
this.message = message;
notify();
}
public synchronized String retrieveMessage(){
while(request == false){
try{
wait();
}catch (InterruptedException e){}
}
request = false;
notify();
return message;
}
}
不推荐这两个方法?不会吧,这是Java 中同步的关键方法,可以说是强烈推荐要了解清楚的方法呀。 :)
怎么Wait()和notify()都在一个方法里?
我还以为是A线程Wait, 然后B线程去notify A呢?
讲讲原理好么? 不要就写一堆代码就不管了。就象上面的例子:
request = false;
notify();
return message;
这个notify()到底在通知谁,自己还是别人呢?如果是别人,这个notify()怎么知道是该通知哪个线程?(假如我有几个线程)
我希望有解释,而不是一堆代码贴过来......
private boolean request; // request 如果把名字改成 isFull 会更加有说明意义,这个标志说明了信箱是不是空,是不是可以取出信。
private String message;
public synchronized void storeMessage(String message){
while(request == true){
try{
wait(); // 如果信箱是满的,放弃自已对信箱获得的锁,让别的对象有机会获得这个锁,同时自已也在等待重新获得这个锁
}catch (InterruptedException e){}
}
request = true; // 设置信箱满的标志
this.message = message;
notify(); // 通知所有等待这个锁的对象,其实此处可能用 notifyAll() 更好?
}
retrieveMessage() 几乎与 storeMessage() 一模一样,就不再注解了。不知这样说明行不行,有错误欢迎指出。
在WINDOW下编程,一个线程等待时,可以由另一个线程通过发送MESSAGE,从而唤醒它。而不是
希望在另一个线程里通过调用该线程start()来驱动。
我现在没搞清楚,在调用WAIT()时,发生了什么事情。调用NOTIFY()时,又发生了什么事情。NOTIFY()是如何去通知其他线程的?
还是那句话,不要贴一堆代码,要讲原理。
确实如ENDER所说: 只要能notify()一个wait()的线程而已…… :)
notify()->随机地从等待队列删除一个线程,也就是说,该线程进入执行状态
notifyall()->删除所有在等待队列中的线程,按线程的优先级执行不推荐使用notify():
因为这是随机地从等待队列中取一个线程执行,我们不能通过设定优先级进行控制,如果,随机抽取的线程不能往前执行,这就有可能产生死锁,所以,建议使用notifyall()
但是确实推荐notifyAll(),因为这至少让所有的等待线程有机会被执行。
有个SOCKET的线程,收到数据后,我想通知另一个线程干活。但同时还有其他的线程,我想
让他们继续睡觉。
就这么简单,在WINDOW下很容易作的,在JAVA就不知道了
同步代码同一时间只能由一个线程执行,在此之前线程必须首先得到这段同步代码的锁。如果锁在另一个线程的控制之下,这个线程就会进入找锁状态,直到另一个程序释放锁。 当wait()被调用后,当前线程也会释放锁。所以就会出现一种情况: 多个线程都处于wait状态。 当条件符合时,notify()被调用,它所作的是随意从等待线程中选择一个,唤醒。记住,在java中,notify()和wait() 只能由同步代码来执行,而不是某个线程。你的socket可以参照上面的mailbox嘛
一个线程发数据,发完以后置一个标志,另一段同步代码得到这个标志就通知 另一个线程。
你不用担心会通知错误,这两个线程就算都处于wait()状态,也是在不同的waiting pool中。
(每一个锁都有自身的waiting pool)。
我换种方法吧。
我是这样认为的:线程获得了synchronize作用范围内的对象的锁。如synchronized是针对某个方法,那么它获得了整个方法内所用对象的锁,所以这样用要小心。如synchronized只针对某段代码体,那么它之获得这段代码体内对象的锁,这比较容易控制。
这样两个线程需同步时,可简单地选一把锁(某个对象),比如是:Object lock;
Thread1 {
synchronized(lock) { //获得lock
……
wait(); //放弃lock,等待
……
}
}
Thread2 {
synchronized( lock ) { //获得lock
……
lock.notifyAll(); //放弃lock,通知所有等待lock的线程。
}
}也就是lock,notify针对的是对象。