Topic: wait() and notify()

  Print this page

1.wait() and notify() Copy to clipboard
Posted by: daywalker
Posted on: 2003-09-26 21:23

有一段程序:
public class WaitAndNotify extends Thread{
  public synchronized void run(){
    try{
      wait();
    }catch(InterruptedException e){
      e.printStackTrace(System.err);
    }
  }
  
  public static void main(String[] args){
    WaitAndNotify wan=new WaitAndNotify();
    wan.start();
    synchronized(wan){ //1
      wan.notify(); //1
    } //1
  }
}

按照我的想法程序应该按下面的顺序运行:
1 开始新的线程(wan.start())
2 线程在run()方法中被阻塞
3 因为是调用的wait()阻塞线程,所以wan对象上的锁应当被放弃,从而使//1的代码被执行,线程被唤醒,程序得以继续执行

可实际情况是:
wan.start()被调用,线程被阻塞,没有继续向下执行。不知道是什么原因?

2.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: java8964
Posted on: 2003-09-26 23:28

In a thread, don't synchronized the run method. It is very easy to create deadlock if you do that.

Why you want to call wait() in the run method?

3.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: daywalker
Posted on: 2003-09-27 08:15

这段程序仅仅作为一个例子,想验证一下wait()是否会释放锁

4.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: lemon2000
Posted on: 2003-09-29 10:32

一、按我的理解,锁是在notify()时被释放的;
二、一个线程在wait()时挂起,等待另一个线程用notify()去踢醒它,而你在主线程里面使用wan.notify()相当于一个人睡着了,又一相情愿地幻想某一时候自己能踢自己一脚,把自己叫醒,应该是用Thread.notify()或Thread.currentThread().notify(),由主线程唤醒子线程,具体的我没有试验,你自己试试

5.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: dog72
Posted on: 2003-09-29 10:51

不会吧!你加一条输出看看,notify肯定会被调用
不过这个程序的问题是你不能够确定指出程序的结果,这个程序有两个可能的结果:
1。notify在wait之前被调用,程序挂起
2。notify在wait之后被调用,程序退出

6.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: dog72
Posted on: 2003-10-09 13:30

没人愿意讨论这个问题吗?搂主和楼上各位的理解都是有问题的呀!

7.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: Biubiu
Posted on: 2003-10-09 13:40

你的理解没有问题,但是你没有注意到wait和notify是在两个线程中执行的。要达到你想要的结果,你必须保证notify在wait之后执行。可是,wait和notify是在两个线程中执行,无法保证这一点。

可以在wan.start()之后加上Thead.sleep(1000),这样一般情况下,就会得到你想要的结果。但是不是100%!

8.Re:wait() and notify() [Re: lemon2000] Copy to clipboard
Posted by: dog72
Posted on: 2003-10-09 16:00

lemon2000 wrote:
一、按我的理解,锁是在notify()时被释放的;

理解错误,锁是在synchronized时候加上的,wait时候释放的,notify是唤醒


二、一个线程在wait()时挂起,等待另一个线程用notify()去踢醒它,而你在主线程里面使用wan.notify()相当于一个人睡着了,又一相情愿地幻想某一时候自己能踢自己一脚,把自己叫醒,应该是用Thread.notify()或Thread.currentThread().notify(),由主线程唤醒子线程,具体的我没有试验,你自己试试

理解错误,Thread().notify不是唤醒这个Thread,而是唤醒以这个Thread实例为同步标志的线程。

9.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: java_archon
Posted on: 2003-10-09 20:09

同意dog72的意见.(l两个发言都同意)

实际上在java中隐藏(混淆)了一些线程中的概念
比如monitor,mutex, condition value.

synchronized实际上就是monitor,它通过内部的互斥信号量mutex来实现
condition value是另一种形式的互斥. 在java中对应的就是wait(), notify()

你可以找一段 生产/消费的 典型代码看一下.

10.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: lemon2000
Posted on: 2003-10-10 12:43

up

11.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: kingwzb
Posted on: 2003-10-12 22:01

严重同意dog72,在这里我总结几条Java多线程用法:
1.sycronized关键字是给对象加锁。
2.wait,notify操作是在操作对象锁的机制上实现同步,故它们只能在sycronized语句块中使用。
3.sleep不会释放锁。
4.wait操作会释放锁。
5.notify是唤醒一个等待锁的线程,若没有等待的线程,则不做任何事。
6.sleep能使较低优先级和较高优先级线程有执行机会,而yield只能使同优先级线程获得执行机会!
7.不要使用已被标为废弃的resume,stop,suspend,因为它们会导致死锁。

12.Re:wait() and notify() [Re: daywalker] Copy to clipboard
Posted by: lemon2000
Posted on: 2003-10-29 11:26

建议大家看一下《Java Thread Programming》
里面有许多线程设计的技巧


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923