java多线程——线程通信
一、线程通信目标
1、线程通信的目标是使线程间能够互相发送信号
2、线程通信使线程能够等待其他线程的信号
二、几种方式
1、通过共享对象
2、忙等待
线程 B 运行在一个循环里,以等待信号 (不释放cpu)
3、wait,notify和notifyAll
wait会使线程进入睡眠或者非运行状态,释放cpu使用权;
线程必须在同步块里调用 wait()或者 notify();
当一个线程调用一个对象的 notify()方法,正在等待该对象的所有线程中将有一个线程被唤醒并允许执行(校注:这个将被唤醒的线程是随机的,不可以指定唤醒哪个线程)。同时也提供了一个 notifyAll()方法来唤醒正在等待一个给定对象的所有线程;
三、信号丢失
notify()和 notifyAll()方法不会保存调用它们的方法,因为当这两个方法被调用时,有可能没有线程处于等待状态。通知信号过后便丢弃了。因此,如果一个线程先于被通知线程调用 wait()前调用了 notify(),等待的线程将错过这个信号。
为了避免丢失信号,必须把它们保存在信号类里。
四、假唤醒
线程有可能在没有调用过 notify()和 notifyAll()的情况下醒来。这就是所谓的假唤醒(spurious wakeups)。
为了防止假唤醒,保存信号的成员变量将在一个 while 循环里接受检查,而不是在 if 表达式里。这样的一个 while 循环叫做自旋锁(校注:这种做法要慎重,目前的 JVM 实现自旋会消耗 CPU,如果长时间不调用 doNotify 方法,doWait 方法会一直自旋,CPU 会消耗太大)。被唤醒的线程会自旋直到自旋锁(while 循环)里的条件变为 false。
五、不要在字符串常量或全局对象中调用 wait()
在空字符串作为锁的同步块(或者其他常量字符串)里调用 wait()和 notify()产生的问题是,JVM/编译器内部会把常量字符串转换成同一个对象;
应该使用对应唯一的对象
java多线程——线程通信的更多相关文章
- java多线程-线程通信
线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 通过共享对象通信 忙等待 wait(),notify()和 notifyAll() 丢失的信号 假唤醒 多线 ...
- Java多线程——线程之间的协作
Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...
- java 多线程—— 线程让步
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- java 多线程—— 线程等待与唤醒
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java多线程--线程及相关的Java API
Java多线程--线程及相关的Java API 线程与进程 进程是线程的容器,程序是指令.数据的组织形式,进程是程序的实体. 一个进程中可以容纳若干个线程,线程是轻量级的进程,是程序执行的最小单位.我 ...
- Java多线程-线程的同步(同步方法)
线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...
- Java多线程——线程的优先级和生命周期
Java多线程——线程的优先级和生命周期 摘要:本文主要介绍了线程的优先级以及线程有哪些生命周期. 部分内容来自以下博客: https://www.cnblogs.com/sunddenly/p/41 ...
- Java多线程——线程的创建方式
Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...
- Java多线程——线程的死锁
Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...
随机推荐
- canvas一周一练 -- canvas绘制中国银行标志(4)
运行效果: <!DOCTYPE html> <html> <head> </head> <body> <canvas id=" ...
- JMeter在linux上分布式压测遇到的坑(三)
master和slave机要在同一网段内,才能做分布式(Jmeter要配环境变量,这样不用手动起server) 分布式不成功,解决方案: 1.master端和slave端要ping通 2.ping通后 ...
- CAD得到ImageMark数据(com接口VB语言)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- 实现加载页Loading Page 的几种方法
网页也可以像原生应用那样加入进度条或者其他的loading效果带来更好的等待体验,这里归纳几种我收集的实现loading page的方法,这几种方法在交互上都有利有弊,适用于不同应用.(PS:以下方法 ...
- WebService接口数据传输加密
1.加密流程 客服端--->加密文本------>服务端接收到加密文本,通过固定加密密文进行解密,然后做相应处理------------>返回结果 2.固定密文创建 密文创建有很多种 ...
- 【转载】dubbo约束的引入(解决eclipse中报错问题)
在采用分布式系统架构时,我们会经常使用到阿里巴巴的dubbo的分布式框架. 在相关xml配置了dubbo的约束依赖后,即使能上网eclipse.myeclipse等IDE也是无法识别dubbo的相关约 ...
- 在PL/SQL DEV里面有把锁一样的按钮,点击它会跳出“these query result are not updateable,include the ROWID to get updateab
在PL/SQL DEV里面有把锁一样的按钮,点击它会跳出“these query result are not updateable,include the ROWID to get updateab ...
- C++ string 是否以‘\0’结尾 讨论
转载https://blog.csdn.net/qq_31930499/article/details/80374310 之前在某篇文章中看到,C语言字符串是以’\0’结尾的,但是C++string类 ...
- vue子组件向父组件传递参数的基本方式
子组件: this.$emit('transferUrl', this.picUrl) 父组件: 引入子组件<pics @transferUrl="gettransferUrl&quo ...
- 【01】bootstrap基本信息
[01]基本信息 中文官网:http://www.bootcss.com/ 英文官网:https://github.com/twbs/bootstrap/ 支持IE8+ CND : htt ...