Java多线程基础-第一节5:wait和notify
Posted 我擦我擦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程基础-第一节5:wait和notify相关的知识,希望对你有一定的参考价值。
文章目录
由于线程之间的执行是抢占式的,所以线程之间的执行的先后顺序难以预知。但在实际开发中有时我们需要各个线程以特定的顺序执行,例如生产者与消费者模型中
- 只有生产者线程生产出了产品消费者线程才能去取
- 只有消费者线程消费了产品(有冗余空间后)生产者线程才能生产
在Java多线程中,要完成这个协调工作会涉及如下方法
wait()/wait(long timeout)
:让当前线程进入等待状态notify()
:唤醒在当前对象上等待的线程notifyAll()
:同上
注意:wait
,notify
,notifyAll
都是Object
类的方法,这意味着可以使用任意类的实例能都调用这些方法
一:wait()方法
wait()方法:线程执行到wait
就会发生阻塞,直到另一个线程调用notify
将此wait
唤醒。wait
要搭配synchronized
使用,脱离synchronized
使用wait会直接抛出异常。执行到wait
会做以下三件事情
- 释放当前的锁
- 使线程进入等待
- 满足一定条件,结束等待,尝试获取锁
wait结束等待的条件有
- 其他线程调用该对象的
notify
方法 - wait等待时间超时(
wait(long timeout)
) - 其他线程调用该等待线程的
interrupted
方法,导致wait
抛出InterruptedException
如下
public class TestDemo
public static void main(String[] args)
Object object = new Object();
System.out.println("wait之前");
synchronized (object)
try
object.wait();
catch (InterruptedException e)
throw new RuntimeException(e);
System.out.println("wait之后");
二:notify()方法
notify()方法:用于唤醒等待的线程,需要在同步方法或同步块中调用。注意
- 如果有多个线程等待,则由线程调度器随机挑选出一个处于
wait
状态的线程 - 在
notify
方法之后,当前线程不会马上释放该对象锁,在退出同步代码块之后才会释放对象锁
如下是一个典型的例子
public class TestDemo
public static void main(String[] args)
//准备一个对象,需要保证wait和notify是同一个对象
Object object = new Object();
//第一个线程,进行wait操作
Thread t1 = new Thread("t1")
@Override
public void run()
while(true)
synchronized (object)
System.out.println(Thread.currentThread().getName() + "进入并占用锁,持续3s");
try
Thread.sleep(3000);
catch (InterruptedException e)
throw new RuntimeException(e);
try
System.out.println(Thread.currentThread().getName() + "等待并释放锁");
object.wait();
catch (InterruptedException e)
throw new RuntimeException(e);
System.out.println("等待结束," + Thread.currentThread().getName() + "重新获取到锁");
;
t1.start();
//第二个线程,进行notify
Thread t2 = new Thread("t2")
@Override
public void run()
while(true)
synchronized (object)
System.out.println(Thread.currentThread().getName() + "进入并占用锁,持续3s");
try
Thread.sleep(3000);
catch (InterruptedException e)
throw new RuntimeException(e);
System.out.println(Thread.currentThread().getName() + "进行notify");
object.notify();
System.out.println("notify完成,让" + Thread.currentThread().getName() + "歇3s");
try
Thread.sleep(3000);
catch (InterruptedException e)
throw new RuntimeException(e);
System.out.println(Thread.currentThread().getName() + "已处在synchronized外,再歇10s");
try
Thread.sleep(12000);
catch (InterruptedException e)
throw new RuntimeException(e);
;
t2.start();
下面是一个动图,展示了程序的运行过程
以上是关于Java多线程基础-第一节5:wait和notify的主要内容,如果未能解决你的问题,请参考以下文章
Java多线程基础-第一节1:多线程概念和Java中创建线程的方式
Java多线程基础-第一节4:synchronized关键字(监视器锁monitor lock)和volatile关键字