[温故]图解java多线程设计模式(一)
去年看完的《图解java多线程设计模式》,可惜当时没做笔记,导致后来忘了许多东西,打算再温习下这本书,顺便在这里记录一下~
一、顺序执行、并行、并发
顺序执行:多个操作按照顺序依次执行。
并行:多个任务同时进行,同一时间内可以执行多个任务,这种方式,叫做并行执行,比如多核处理器,多个核可以同时处理多个任务。
并发:多个任务通过切分时间段,来达到“同时进行”的效果,比如单核处理器,在“同时”处理多个任务时,就会不停的切换来执行不同的任务,不可能有同一时间执行不同任务的情况。
下面引用别人的一句话来说明下并行和并发:
并发是两个任务可以在重叠的时间段内启动,运行和完成。并行是任务在同一时间运行,例如,在多核处理器上。 并发是独立执行过程的组合,而并行是同时执行(可能相关的)计算。 并发是一次处理很多事情,并行是同时做很多事情。
应用程序可以是并发的,但不是并行的,这意味着它可以同时处理多个任务,但是没有两个任务在同一时刻执行。
应用程序可以是并行的,但不是并发的,这意味着它同时处理多核CPU中的任务的多个子任务。
一个应用程序可以即不是并行的,也不是并发的,这意味着它一次一个地处理所有任务。
应用程序可以即是并行的也是并发的,这意味着它同时在多核CPU中同时处理多个任务。
二、synchronized修饰符
当我们说一个线程获得锁以后,则意味着这个线程可以执行当前对象(或类)里的synchronized方法,而且他线程则需要排队等待该线程释放锁以后才可能获得锁,进而执行锁里面的程序。
synchronized修饰后,存在对象锁和类锁两种类型。
2.1:对象锁
synchronized (this){
...略
}
2.2:类锁
synchronized (XXX.class){
...略
}
2.3:区别和作用域
对象锁指的是当前线程获得了某个实例的锁,假如有个Word类,有A、B两个同步方法,C属于普通方法,如图所示:
图1
可以发现,对象锁的作用域只针对当前对象生效,就像w1和w2里的A方法可以被不同的线程同时执行,但是同一个对象内的同步块,却只允许持有当前对象锁的线程执行,如t2、t3均被挡在了外面,当t1释放锁以后,t2、t3才会重新竞争锁,竞争到锁以后就会执行自己想要执行的同步逻辑。
类锁指的是当前线程获得了某个类的锁,还是Word类,有A、B两个static方法(静态方法属于类方法,加synchronized修饰符后等效于上面提到的synchronized(Word.class)),C属于普通static方法,如图所示:
图2
跟上面相比较,这里的t5受到了t1的影响,因为t1获得了Word类的锁,w1和w2共属一个类,因此t1获得类锁以后,其他线程想要访问这个类里的同步块,就得等到t1释放锁以后才可以继续竞争锁然后执行自己想要执行的同步逻辑。
三、线程间的通信
3.1:Wait
这几个方法是属于每个实例对象的,所有实例都拥有一个“等待队列”(虚拟概念,实例里并不存在该字段),它是在实例的wait方法调用后存放停止操作线程的队列。执行wait方法后,线程进入当前实例的“等待队列”,以下几种情况可以让线程退出“等待队列”:
①其他线程调用notify、notifyAll方法来将其唤醒
②其他线程调用interrupt来将其唤醒
③wait方法本身超时
当执行了下面的代码:
obj.wait();
我们可以说当前线程在obj上发生了等待,当前线程进入了obj的“等待队列”,此时当前线程会让出锁,让其他线程继续竞争获得该实例的锁(因此这里有个规则,调用wait的线程必须持有当前实例对象的锁)
过程如下图:
图3
3.2:notify
现在先来介绍下notify,该方法会将等待队列里的线程取出,让其退出等待并参与锁竞争然后继续执行上次wait后没有执行完的语句。整体过程如下图所示:
图4
可以看到,t1在被挂起后,会因为t2调用了同实例的notify方法,而让t1被从等待队列里释放,重新加入到所得竞争力,t2执行完毕后释放锁,锁又再次被t1竞争到,t1将继续执行上次被挂起时后面未执行完的语句。
需要指出的是,如果等待队列里的线程是多个,那么被唤醒的那一个,将会是等待队列里所有线程随机的一个,不会特定哪一个线程会被唤起。
3.3:notifyAll
接下来介绍notifyAll方法,顾名思义,就是将等待队列里的线程全部唤起,然后这些线程将全部加入到锁竞争,竞争到,继续完成上次被挂起时未执行完毕的操作,流程图如下:
图5
说明,当线程调用实例的wait、notify、notifyAll方法有个大前提,就是必须要求该线程拥有该实例的锁,否则会抛IllegalMonitorStateException异常。
在编写程序时,是该选择notify还是选择notifyAll?这个可以指出的是,notifyAll往往更加健壮,而notify由于唤起的线程少,因此效率会更高,但是存在程序停止的风险。
附上使用wait、notify进行线程通信的例子:
[温故]图解java多线程设计模式(一)的更多相关文章
- [温故]图解java多线程设计模式(二)
join & interrupt 这俩方法属于线程对象里的方法,属于线程本身的操作. join方法 用于等待一个线程的终止,等待期间将会阻塞,直到被等待的线程终止结束. 所以join可以用来做 ...
- 《图解Java多线程设计模式》读书笔记
略读中...后面详读的时候,补充经典图片和文字说明
- 图解java多线程设计模式之一一synchronized实例方法体
synchronized实例方法体和synchronized代码块 synchronied void method(){ ....... } 这个等同于下面将方法体用synchronized(this ...
- java多线程设计模式
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt220 java多线程设计模式 java语言已经内置了多线程支持,所有实现Ru ...
- Java多线程设计模式(一)
目录(?)[-] Java多线程基础 Thread类的run方法和start方法 线程的启动 线程的暂时停在 线程的共享互斥 线程的协调 Single Threaded Execution Patte ...
- Java多线程设计模式(4)线程池模式
前序: Thread-Per-Message Pattern,是一种对于每个命令或请求,都分配一个线程,由这个线程执行工作.它将“委托消息的一端”和“执行消息的一端”用两个不同的线程来实现.该线程模式 ...
- Java多线程设计模式(四)
目录(?)[-] Future Pattern Two-Phase Termination Pattern Thread-Specific Storage Pattern Active Object ...
- Java多线程设计模式(三)
目录(?)[-] Read-Wirte Lock Pattern Thread-Per-Message Pattern Worker Thread Pattern Read-Wirte Lock ...
- Java多线程设计模式(二)
目录(?)[-] Guarded Suspension Pattern Balking Pattern Producer-Consumer Pattern Guarded Suspensi ...
随机推荐
- ie高版本浏览器不支持velocity的问题解决
<head><meta http-equiv="X-UA-Compatible" content="IE=5"></head> ...
- unidac 访问sql server 字符查询参数失效问题及解决办法
在帮朋友调试kbmmw 服务器的时候,发现用uindac 访问sql server作为后台时,碰见一个问题. 具体如下: cx.Close; cx.sql.add('select * from T w ...
- Spring MVC3.2 通过Servlet3.0实现文件上传
Servlet3.0规范增加了对文件上传的原生支持,这里记录一下Spring MVC3通过Servlet3上传文件的实现. 配置文件: applicationContext.xml <!-- s ...
- Give $20/month and provide 480 hours of free education
Hi , Hope all is well. Summer is right around the corner, and the Khan Academy team is excited to sp ...
- Dom4j的一个小例子,用于解析xml文件的元素获取方式(转)
import java.io.File; import java.io.IOException; import javax.xml.parsers.ParserConfigurationExcepti ...
- .net 开发者尝试Apache Spark™
本文编译自一篇msdn magazine的文章,原文标题和链接为: Test Run - Introduction to Spark for .NET Developers https://msdn. ...
- MyBatis高级及其SSM框架搭建
代码生成器 首先meaven项目中导入支持包 <dependencies> <!-- https://mvnrepository.com/artifact/mysql/mysql-c ...
- leetcode 84. 柱状图中最大的矩形 JAVA
题目: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高 ...
- linux命令之文件备份与压缩命令
1.tar:打包备份 该命令是将多个命令打包到一起,并且可以实现解压打包.打包是将多个文件或者目录变成一个总的文件,压缩则是将一个大的文件通过压缩算法变成一个小文件. 参数 说明 z(常用) 通过gz ...
- Python3.5 学习七
心灵鸡汤 好书推荐:消费者行为学.围城.活着.盲井.三体.北京折叠 静态方法: @staticmethod #名义上归类管,和类没什么关系,只是引用用"." 在静态方法中,无法访问 ...