没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
一、线程间的通信
(1)为什么要处理线程间的通信
(2)等待唤醒机制
二、案例
(1)案例
1、创建线程
2、解决线程安全问题
3、等待
4、唤醒
5、同步监视器
(2)调用wait和notify需注意的细节
三、wait与sleep的区别
一、线程间的通信
(1)为什么要处理线程间的通信
当我们 需要多个线程 来共同完成一件任务,并且我们希望他们 有规律的执行 ,那么多线程之间需要
一些通信机制,可以协调它们的工作,以此实现多线程共同操作一份数据。(在同步的基础之上解决通
信的问题)
比如:线程A用来生产包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理
的动作,一个是生产,一个是消费,此时B线程必须等到A线程完成后才能执行,那么线程A与线程B之间
就需要线程通信,即—— 等待唤醒机制。
(2)等待唤醒机制
这是多个线程间的一种 协作机制 。
谈到线程我们经常想到的是线程间的 竞争(race) ,比如去争夺锁,但这并不是故事的全部,线程
间也会有协作机制。
在一个线程满足某个条件时,就进入等待状态( wait() / wait(time) ), 等待其他线程执行完
他们的指定代码过后再将其唤醒( notify() );
或可以指定wait的时间,等时间到了自动唤醒;
在有多个线程进行等待时,如果需要,可以使用 notifyAll() 来唤醒所有的等待线程。
wait/notify 就是线程间的一种协作机制。
1. wait:线程不再活动,不再参与调度,进入 wait set 中,因此不会浪费 CPU 资源,也不会
去竞争锁了,这时的线程状态是 WAITING 或 TIMED_WAITING。它还要等着别的线程执行一
个 特别的动作 ,也即“ 通知(notify) ”或者等待时间到,在这个对象上等待的线程从wait set
中释放出来,重新进入到调度队列( ready queue )中。
2. notify:则选取所通知对象的 wait set 中的一个线程释放。
3. notifyAll:则释放所通知对象的 wait set 上的全部线程。
🗳
注意:
被通知的线程被唤醒后也不一定能立即恢复执行,因为它当初中断的地方是在同步块内,而此刻它
已经不持有锁,所以它需要再次尝试去获取锁(很可能面临其它线程的竞争),成功后才能在当初调用
wait 方法之后的地方恢复执行。
总结如下:
如果能获取锁,线程就从 WAITING 状态变成 RUNNABLE(可运行) 状态;
否则,线程就从 WAITING 状态又变成 BLOCKED(等待锁) 状态
二、案例
(1)案例
🌋
案例描述:
使用两个线程打印 1-100。线程1, 线程2 交替打印。
🍰
分析
1、创建线程
这里使用实现的方式创建线程。
在 run 方法里面写上逻辑代码:
class PrintNumber implements Runnable{
//共享100
private int number=1;
@Override
public void run() {
}
}
class PrintNumber implements Runnable{
//共享100
private int number=1;
@Override
public void run() {
//打印数据
while(true){
if(number<=100){
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
}else{
break;
在 main 方法中创建两个线程,如下:
关于number的问题,需要考虑同步。
在if中加一个 sleep ,将问题放大。
目前的代码如下:
}
}
}
}
public class PrintNumberTest {
public static void main(String[] args) {
//创建PrintNumber类的实例
PrintNumber p=new PrintNumber();
Thread t1=new Thread(p,"线程1");
Thread t2=new Thread(p,"线程2");
t1.start();
t2.start();
}
}
public class PrintNumberTest {
public static void main(String[] args) {
//创建PrintNumber类的实例
PrintNumber p=new PrintNumber();
Thread t1=new Thread(p,"线程1");
Thread t2=new Thread(p,"线程2");
t1.start();
t2.start();
}
}
class PrintNumber implements Runnable{
//共享100
private int number=1;
@Override
public void run() {
//打印数据
while(true){
if(number<=100){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
剩余17页未读,继续阅读
资源评论
雨翼轻尘
- 粉丝: 6w+
- 资源: 130
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 电子万年历软件仿真(经过多次修改,保证正确性)
- Unity XR 手势射击控制脚本(适用于任何可手势识别的设备)
- 机械设计全自动电表(NB和IC卡表)控制和上壳装配线sw16可编辑非常好的设计图纸100%好用.zip
- 基于matlab的EAN-13条形码识别系统GUI界面.zip代码53
- matlab基于bp神经网络交通信号标志识别GUI界面13个标志.zip代码54
- 电子万年历答辩实物展示视频mp4格式
- 基于python实现的程序,包括哈希感知算法cvHash,图像切割cvsplit,固定目标检测cvRec(附文档ppt)等
- 计算0-10000之间所有偶数的和
- multiled.zip
- 基于php实现的哈希算法的人脸检索
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功