java对象方法wait,notify

来源:互联网 发布:数据对接的接口及方式 编辑:程序博客网 时间:2024/06/06 13:01

java对象方法wait,notify

wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。
这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。

如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

其中wait方法有三个over load方法:
wait()
wait(long)
wait(long,int)
wait方法通过参数可以指定等待的时长。如果没有指定参数,默认一直等待直到被通知。
可测试代码:

package test2;public class Test10 {    public static void main(String[] args) throws InterruptedException {          Boolean flag=true;        NotifyThread notifyThread =new NotifyThread("notify01",flag);          WaitThread waitThread01 = new WaitThread("waiter01",flag);          WaitThread waitThread02 = new WaitThread("waiter02",flag);          WaitThread waitThread03 = new WaitThread("waiter03",flag);          notifyThread.start();          waitThread01.start();          waitThread02.start();          waitThread03.start();      }  }class NotifyThread extends Thread {     private String name;    private Boolean flag;    public NotifyThread(String name,Boolean flag) {          super(name);          this.name=name;        this.flag=flag;    }      public void run() {          try {              sleep(3000);          } catch (InterruptedException e) {              e.printStackTrace();          }          synchronized (flag) {              //如果添加flag=false会出错illegalMonitorStateException            flag.notifyAll();              System.out.println("notify");        }      }  };  class WaitThread extends Thread {      private String name;    private Boolean flag;    public WaitThread(String name,Boolean flag) {          super(name);          this.name=name;        this.flag=flag;    }      public void run() {          synchronized (flag) {              while (flag!=false) {                  System.out.println(name+" is running");                long waitTime = System.currentTimeMillis();                  try {                      flag.wait();                      System.out.println(getName() + " begin waiting!");                } catch (InterruptedException e) {                      e.printStackTrace();                  }                  waitTime = System.currentTimeMillis() - waitTime;                  System.out.println("wait time :" + waitTime);              }              System.out.println(getName() + " end waiting!");          }      }  }  

参考:http://longdick.iteye.com/blog/453615
结果:
waiter01 is running
waiter02 is running
waiter03 is running
notify
waiter03 begin waiting!
wait time :2998
waiter03 is running
waiter02 begin waiting!
wait time :2999
waiter02 is running
waiter01 begin waiting!
wait time :3000
waiter01 is running
(不同机器可能不一样,另外线程顺序是随机的)
至于为什么会出现
waiter01 is running
waiter02 is running
waiter03 is running
按理说,synchronized获得了flag的锁之后,别的线程不会得到相应的锁(如果你想确认的话,在waitThread里面将synchronized块里面的wait删除,就可以看到只有一个打印输出了)原因就是调用wait之后,被阻塞的线程会释放synchronized的到的锁,然后锁依次被下一个线程取得。
注意:
1:wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()。但是notify()不会立刻立刻释放synchronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁。
2:如果在编写notify时修改了某些条件,使得原来synchronized(obj)里面的已经判断的某些条件改变了,那么会抛出illegalMonitorStateException。

0 0
原创粉丝点击