当前课程知识点:JAVA程序设计进阶 > 第二章 线程(中) > 2.3 线程的等待与唤醒 > Video
这一节我们将介绍线程的等待与唤醒
线程在运行过程当中
有可能会进入一种等待状态
直到有其他线程来唤醒它
就会进入唤醒状态
为了更有效的协调
不同线程之间的工作
我们需要在线程之间建立这种沟通渠道
通过线程之间的对话
来解决线程之间的同步问题
那在java.lang.Object的一些方法
为线程之间的通讯
提供了有效的手段
比如说wait方法
大家需要注意的是
object这个类的这个方法
那它的主要功能是指
在执行同步代码的某个线程中
去等待某个对象
那这个时候该线程要
这个调用wait方法了以后
就要是暂停执行
而进入等待对象x的等待池
并且释放已经获得的对象x的锁
那这时候这个线程
一直要等到其他线程在对象x上
调用notify或者notifyAll方法
才能让它重新获得
这个对象x的锁再继续执行
也就是说顾名思义
wait方法是站在某个线程的角度的话
它想等待某一个对象
而去调用这个wait这个方法
但是等待什么时候结束
是需要其他线程来通知它的
也就是说其他线程要调用
notify方法或者notifyAll方法
那notify的这个功能
是随机唤醒一个等待的线程
然后本线程还继续执行
那线程被唤醒以后
还要等发出唤醒消息者释放监视器
这个期间关键数据仍有可能被改变
然后被唤醒的线程
当它开始执行的时候
一定要判断当前的状态
是否适合自己执行
那notifyAll这个方法呢
它的作用是唤醒所有等待的线程
而本线程还继续执行
那现在wait notify notifyAll方法
这三个方法都属于object
这个类的方法
也就意味着我们java当中
所有的类它都有这个三个方法
那现在我们利用这三个方法
来重新修改一下
我们上述的例子
使得我们线程之间能够进行通讯
那现在我们把上面的例子要改变一下
但是有一个要求
就是说每次的话
这个只能存入一张票
然后每次也只能卖出一张票
你必须卖出一张票以后
才能去存入一张票
那这个时候就需要线程之间
有相互通讯
那通讯的目的是啥呢
比如说我要这个卖票的时候
必须等到那个有票存进来
那我等到什么时候结束呢
就必须由存票的那个线程来通知我说
已经有一张票存进来了
那对于这个要存票的线程
有时候它要往那个
这个票里面存一张票
发现里边已经有一张票了
它存不进去的时候
它就必须也得等待
那等到什么时候呢
等到售票程序把票卖出去以后
反过来告诉这个存票程序说
已经卖不出去了
那个里面有空间了
你接着再往里存
所以这个就相当于两个线程之间
有这种相互的通讯存在
那我们看怎么去改造这个
ticket这个类
我们看ticket的这个synchronized方法
public synchronized void put
if available如果还有存票待售
那你就不允许再往里面存票了
因为你得等人家卖完
因为我们把这个例子修改了之后
加了一个限制就是说那个
就相当于那票箱很小
只有一张票的空间
你要往里面塞一张票
必须等上一张票卖掉了
你才往里面塞
所以在这个方案里面
if available就是说还有存票待售
那这个时候我们这个存票程序
你就不能够往里面塞票了
你就必须等
所以就try wait就是等
然后这个try这个
然后这个后面catch exception
等到什么时候呢
等到另外一个线程要
就是这个去提醒它
后面我们一会儿马上就能看到
假设它等 等待结束了
它就会打印出来
说producer puts synchronized
加上(++number)
然后相当于就生产了一张票
然后available=true
然后这个有票可卖了
这时候notify
这个notify是干啥呢
是存票后唤醒售票程序开始售票
也就是说我这个存票程序
正好已经存了一张票进去了
我就通知你这个售票线程说
你有票可以卖 你赶紧卖
我们接着往下看另外一个方法
public synchronized void Sell
if非available也就是说如果没有存票
那我这个想卖票
我当然卖不出去了
因为没票可卖
没票可卖的话我就只能等
所以try wait 然后catch Exception
那等啊 假设等待结束了
马上我就卖票了
那怎么卖呢
system.out.println
consumer buys synchronized
加上number
然后就试着available等于false
也就是说票卖完了
然后接着紧接着再notify
notify的话就是这个
它目的是唤醒这个存票程序
说我票已经卖了
你可以结束等待
你可以去存票了
所以说我们在sell这个方法里面
notify是和我们上面
那个put方法的wait对应的
这一对是相互配合的
那我们再看一下我们sell这个方法里面
第二行不是有wait吗
就是我售票的这个wait这个方法
实际上是和上面的put方法的
最后一行notify是对应的
它是一个相互等待和唤醒的过程
那在put方法里面它的等待
也就是说我要往里面去存票
由于你票没卖出去
所以我必须等待
等待你票卖出去再往里存
那这种等待的唤醒
是在我们sell方法里面
这个notify来去唤醒它
那反过来说我们在sell这个方法的
第二行wait是说我要卖票
但是你没有票了
我当然卖不了
我当然卖不了的话我只能等
等到什么时候呢
等到put方法里面的那个notify
是因为put方法的时候
我已经往里面存一张票了
然后我就这个notify
就唤醒一下
唤醒一下你这个
要卖票的那个 这个线程
这个时候它就可以继续往下卖了
所以这个wait和notify
这个先后一对一对配合的作用
是非常有意思的
大家一定要看明白
那这个程序继续往下
这个实现的话
就是把producer这个和consumer
都给实现了
但实际上这个
这部分代码基本上没有什么变化
有变化的是刚才我们上面的
那个tickets这个类
下面我们看一下运行结果
这个运行结果的话
就是能看出来我们这个
都是放一张票卖一张票
存一张票卖一张票
存一张票卖一张票
基本上实现了这个效果
那在这个程序的过程当中
我们可以看到当consumer线程
售出票以后
它把available变成false
然后当producer把线程放入票以后
available就变为true
那只有available为true的时候
consumer线程才能售票
否则它就必须等待这个producer线程
放入新的票后的这个通知
然后只有当available为false的时候
我们producer才能放票
否则就必须一直等待
这个consumer线程售出票后的这个通知
所以这个等待和通知
这是相辅相成的
刚才这一节我们通过例子
阐述了wait和notify方法的用法
-1.0 导学
--Video
-1.1 线程的基本概念
--Video
-1.1 线程的基本概念--作业
-1.2 通过Thread类创建线程
--Video
-1.2 通过Thread类创建线程--作业
-1.3 线程的休眠
--Video
-1.3 线程的休眠--作业
-1.4 Thread类详解
--Video
-1.5 通过Runnable接口创建线程
--Video
-1.5 通过Runnable接口创建线程--作业
-1.6 线程内部的数据共享
--Video
-2.0 导学
--Video
-2.1 线程同步的思路
--Video
-2.2 线程同步的实现方式—Synchronization
--Video
-2.3 线程的等待与唤醒
--Video
-2.4 后台进程
--Video
-2.5 线程的生命周期与死锁
--Video
-2.6 线程的调度
--Video
-3.0 导学
--Video
-3.1 线程安全与线程兼容与对立
--Video
-3.2 线程的安全实现-互斥同步
--Video
-3.3 线程的安全实现-非阻塞同步
--Video
-3.4 线程的安全实现-无同步方案
--Video
-3.5 锁优化
--Video
-4.0 导学
--Video
-4.1 URL对象
--Video
-4.2 URLConnection对象
--Video
-4.3 Get请求与Post请求
--Video
-4.4 Socket通信原理
--Video
-4.5 Socket通信实现
--Video
-5.0 导学
--Video
-5.1 Socket 多客户端通信实现
--Video
-5.2 数据报通信
--Video
-5.3 使用数据报进行广播通信
--Video
-5.4 网络聊天程序
--Video
-6.0 导学
--Video
-6.1 Java虚拟机概念
--Video
-6.2 Java虚拟机内存划分
--Video
-6.3 Java虚拟机类加载机制
--Video
-6.4 判断对象是否存活算法及对象引用
--Video
-6.5 分代垃圾回收
--Video
-6.6 典型的垃圾收集算法
--Video
-6.7典型的垃圾收集器
--Video
-7.0 导学
--Video
-7.1 集合框架与ArrayList
--Video
-7.2 LinkedList
--Video
-7.3 HashMap与HashTable
--Video
-7.4 TreeMap与LinkedHashMap
--Video
-7.5 HashSet
--Video
-8.0 导学
--Video
-8.1 Java反射机制
--Video
-8.2 Java静态代理
--Video
-8.3 Java动态代理
--Video
-8.4 Java 反射扩展-jvm加载类原理
--Video
-8.5 Java进阶课程总结
--Video