java wait与notify方法

一、wait与notify

1.wait()方法

语义:使得当前线程立刻停止运行,处于等待状态(WAIT),并将当前线程置入锁对象的等待队列中,直到被通知(notify)或被中断为止。

使用条件:wait方法只能在同步方法或同步代码块中使用,而且必须是内建锁。wait方法调用后立刻释放对象锁

wait方法的重载

1)public final void wait() throws InterruptedException——死等,直到被唤醒或中断

2)public final native void wait(long timeout) throws InterruptedException——超时等待:若在规定时间内未被唤醒,则线程退出,单位:毫秒

3)public final void wait(long timeout, int nanos) throws InterruptedException——在2的基础上增加了纳秒控制

2.notify()方法

语义:唤醒处于等待状态的线程

使用条件:notify()也必须在同步方法或同步代码块中调用,用来唤醒等待该对象的其他线程。如果有多个线程在等待,随机挑选一个线程唤醒(唤醒哪个线程由JDK版本决定)。notify方法调用后,当前线程不会立刻释放对象锁,要等到当前线程执行完毕后再释放锁。

3.notifyAll()方法

唤醒所有处于等待状态的线程

class myThread implements Runnable{
    private boolean flag ;
    private Object object ;

    myThread(boolean flag, Object o){
        this.flag = flag;
        this.object = o;
    }
    private void waitThread(){
        synchronized (object) {
            System.out.println(Thread.currentThread().getName() + "wait begin...");
            try {
                object.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "wait end...");
        }
    }
    private void notifyThread(){
        synchronized (object) {
            System.out.println(Thread.currentThread().getName() + "notify begin...");
            object.notify();
            System.out.println(Thread.currentThread().getName() + "notify end...");
        }
    }
    @Override
    public void run() {
        if(flag){
            waitThread();
        }else {
            notifyThread();
        }
    }
}
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        myThread mt2 = new myThread(false,object);
        Thread thread1 = new Thread(mt2,"线程B ");
        for (int i = 0;i<10;i++) {
            myThread mt = new myThread(true,object);
            Thread thread = new Thread(mt,"线程A "+i);
            thread.start();
        }
        Thread.sleep(1000);
        thread1.start();
    }
}

输出

这段代码中,开启了10个线程去执行waitThread()方法,可以发现10个线程都处于等待状态,1秒后开启一个线程去执行notifyThread(),可见notify唤醒了0号线程,0号线程等待结束。当我们把notify()改成notifyAll()后,会唤醒所以等待的线程,效果如下,而且可以发现notify没有立刻释放对象锁,唤醒后的顺序与等待的顺序正好相反,所以他是等到当前线程执行完毕后再释放锁。

二、线程出现阻塞的情况(线程由运行到阻塞)

1.线程调用sleep()方法。立刻交出CPU,但不释放锁

2.线程调用阻塞式IO(BIO)方法

3.线程获取锁失败进入阻塞状态

4.线程调用wait()方法

5.线程调用suspend()方法,将线程挂起,此方法容易导致死锁

每个锁对象都有2个队列。一个称为同步队列,存储获取锁失败的线程。另一个称为等待队列,存储调用wait()等待的线程。将线程唤醒实际上是将处于等待队列的线程移到同步队列中竞争锁。

 

 

 

  • 9
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值