Java中wait,notify方法

一.介绍

wait(),notify(),notifyAll()方法是位于Object类的方法,这三个方法调用的都是jvm的 native方法。

  • wait()方法:持有该对象的线程处于等待,让出对象的控制权
  • notify()方法:通知正在等待这个对象控制权的线程可以继续运行
  • notifyAll()方法:通知所有等待这个对象控制权的线程继续运行

二.解释说明

wait方法,有三个重载的方法:
- wait()
- wait(long time)
- wait(long time1,int time2)

1.wait()方法

wait方法将当前线程置入休眠状态,知道被通知或中断为止,在调用wait()方法前,必须获取对象级别锁,因此它只能在同步方法和同步块调用。当调用wait()方法,当前线程释放锁,在从wait()方法返回前,线程与其他线程竞争重新获得锁。


2.notify()方法

该方法也要在同步方法和同步块中调用,在调用前必须获得对象级别锁,没有则抛出异常。
该方法用来通知那些等待该对象的对象锁的其他线程,如果有多个线程等待,则挑选出一个其中出于wait状态的线程来发出通知,并使得它获取对象锁。(执行notify方法后,当前线程并不会马上释放该对象锁,要等到程序退出synchronized代码块后,当前线程才可以释放对象锁,处于wait状态的线程才可以获取该对象锁
下面举个例子:

public class TestWatiNotify {
    public static Object obj=new Object();
    public static void main(String[] args){
        Thread1 t1=new Thread1();
        t1.setName("线程1");
        Thread2 t2=new Thread2();
        t2.setName("线程2");
        t1.start();
/*      try {
            Thread.sleep(100);
        }catch (InterruptedException e){
            e.printStackTrace();
        }*/
        t2.start();
    }
    static class Thread1 extends Thread{
        @Override
        public void run(){
            synchronized (obj){
                System.out.println("调用wait方法前");
                try{
                    obj.wait();
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println("线程"+Thread.currentThread().getName()+"获取到锁");
            }
        }
    }
    static class Thread2 extends Thread{
        @Override
        public void run(){
            synchronized (obj){
                obj.notify();
                System.out.println("线程"+Thread.currentThread().getName()+"调用了notify方法");
            }
            System.out.println("线程"+Thread.currentThread().getName()+"释放了该锁");
            try{
                Thread.sleep(100);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("线程"+Thread.currentThread().getName()+"结束");
        }
    }
}

执行完上述代码,出现下面的结果:

调用wait方法前
线程线程2调用了notify方法
线程线程2释放了该锁
线程线程1获取到锁
线程线程2结束

分析一下结果我们发现,首先是线程1获取了对象锁,然后执行了wait()方法,所以释放了该对象锁,线程2获取了对象锁,它调用了notify()方法,在执行完当前线程的同步块后,线程1获取到对象锁,继续执行线程1同步块中wait方法之后的代码,同时线程2也在同步块后面的代码。我们发现,线程在唤醒等待该对象的其他线程,并释放掉对象锁的时候,这时候对象出于空闲状态,如果有多个出于等待的线程,那么它们会竞争该对象锁,但是不影响没有加该对象锁的线程执行。

3.notifyAll()方法

与notify()方法工作原理差不多,有一些小的差异:
notifyAll使所有原来在该对象上wait的线程退出wait状态(但并非全部获取对象锁,它们会竞争,只会有一个线程获取该对象锁),在notifyAll线程退出当前的synchronized同步块后,才参与竞争该对象锁,如果有一个线程获取到该对象锁,它会继续执行,直到执行完同步块释放对象锁,其他的被唤醒的线程将继续竞争对象锁,一直进行下去,直到所有被唤醒的线程都执行完毕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值