当前课程知识点:JAVA程序设计进阶 >  第二章 线程(中) >  2.3 线程的等待与唤醒 >  Video

返回《JAVA程序设计进阶》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《JAVA程序设计进阶》慕课在线视频列表

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方法的用法

JAVA程序设计进阶课程列表:

第一章 线程(上)

-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

第六章 Java虚拟机

-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

第七章 深入集合Collection

-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

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。