@@ -8,7 +8,7 @@ typora-copy-images-to: img
8
8
9
9
## 1.1 多线程引入
10
10
11
- ![ ] ( http:// img.blog.csdn.net/20150827214823243 )
11
+ ![ ] ( img/thread_09.png )
12
12
13
13
由上图中程序的调用流程可知,这个程序只有一个执行流程,所以这样的程序就是单线程程序。假如一个程序有多条执行流程,那么,该程序就是多线程程序。
14
14
@@ -21,7 +21,7 @@ typora-copy-images-to: img
21
21
在一个操作系统中,每个独立执行的程序都可称之为一个进程,也就是“正在运行的程序”。目前大部分计算机上安装的都
22
22
是多任务操作系统,即能够同时执行多个应用程序,最常见的有Windows、Linux、Unix等。在本教材使用的Windows操作系统下,鼠标右键单击任务栏,选择【启动任务管理器】选项可以打开任务管理器面板,在窗口的【进程】选项卡中可以看到当前正在运行的程序,也就是系统所有的进程,如chrome.exe、QQ.exe等。任务管理器的窗口如图所示。
23
23
24
- ![ 1500693373975 ] ( img/1500693373975 .png )
24
+ ![ 多线程 ] ( img/thread_10 .png )
25
25
26
26
在多任务操作系统中,表面上看是支持进程并发执行的,例如可以一边听音乐一边聊天。但实际上这些进程并不是同时运行的。在计算机中,所有的应用程序都是由CPU执行的,对于一个CPU而言,在某个时间点只能运行一个程序,也就是说只能执行一个进程。操作系统会为每一个进程分配一段有限的CPU使用时间,CPU在这段时间中执行某个进程,然后会在下一段时间切换到另一个进程中去执行。由于CPU运行速度很快,能在极短的时间内在不同的进程之间进行切换,所以给人以同时执行多个程序的感觉。
27
27
@@ -41,7 +41,7 @@ typora-copy-images-to: img
41
41
42
42
多线程程序的执行过程如图所示
43
43
44
- ![ 1500693584730 ] ( img/1500693584730 .png )
44
+ ![ thread ] ( img/thread_11 .png )
45
45
46
46
图中所示的多条线程,看似是同时执行的,其实不然,它们和进程一样,也是由CPU轮流执行的,只不过CPU运行速度很快,故而给人同时执行的感觉。
47
47
@@ -312,7 +312,7 @@ public class CallableDemo {
312
312
313
313
运行结果:
314
314
315
- ![ ] ( http:// img.blog.csdn.net/20150810174959628 )
315
+ ![ ] ( img/thread_12.png )
316
316
317
317
318
318
实现Callable的优缺点
@@ -343,7 +343,7 @@ new Thread(new Runnable() {
343
343
344
344
## 2.5 单线程和多线程的运行流程
345
345
346
- ![ 1500693721559 ] ( img/1500693721559 .png )
346
+ ![ thread ] ( img/thread_13 .png )
347
347
348
348
从图可以看出,单线程的程序在运行时,会按照代码的调用顺序执行,而在多线程中,main()方法和MyThread类的run()方法却可以同时运行,互不影响,这正是单线程和多线程的区别。
349
349
@@ -369,7 +369,7 @@ Java使用的是抢占式调度模型。
369
369
370
370
在应用程序中,如果要对线程进行调度,最直接的方式就是设置线程的优先级。优先级越高的线程获得CPU执行的机会越大,而优先级越低的线程获得CPU执行的机会越小。线程的优先级用1~ 10之间的整数来表示,数字越大优先级越高。除了可以直接使用数字表示线程的优先级,还可以使用Thread类中提供的三个静态常量表示线程的优先级,如表所示。
371
371
372
- ![ 1500694154099 ] ( img/1500694154099 .png )
372
+ ![ thread ] ( img/thread_14 .png )
373
373
374
374
程序在运行期间,处于就绪状态的每个线程都有自己的优先级,例如main线程具有普通优先级。然而线程优先级不是固定不变的,可以通过Thread类的setPriority(int newPriority)方法对其进行设置,该方法中的参数newPriority接收的是1~ 10之间的整数或者Thread类的三个静态常量。
375
375
@@ -646,13 +646,13 @@ public class Example08 {
646
646
647
647
三种状态的切换如下图所示:
648
648
649
- ![ ] ( http://i.imgur.com/xxOWT2V.jpg )
649
+ ![ ] ( img/thread_15.png )
650
650
651
651
# 4. 线程的生命周期
652
652
653
653
在Java中,任何对象都有生命周期,线程也不例外,它也有自己的生命周期。当Thread对象创建完成时,线程的生命周期便开始了。当run()方法中代码正常执行完毕或者线程抛出一个未捕获的异常(Exception)或者错误(Error)时,线程的生命周期便会结束。线程整个生命周期可以分为五个阶段,分别是新建状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)和死亡状态(Terminated),线程的不同状态表明了线程当前正在进行的活动。在程序中,通过一些操作,可以使线程在不同状态之间转换,如图所示。
654
654
655
- ![ 1500693803598 ] ( img/1500693803598 .png )
655
+ ![ thread ] ( img/thread_16 .png )
656
656
657
657
图中展示了线程各种状态的转换关系,箭头表示可转换的方向,其中,单箭头表示状态只能单向的转换,例如线程只能从新建状态转换到就绪状态,反之则不能;双箭头表示两种状态可以互相转换,例如就绪状态和运行状态可以互相转换。通过一张图还不能完全描述清楚线程各状态之间的区别,接下来针对线程生命周期中的五种状态分别进行详细讲解,具体如下:
658
658
@@ -698,7 +698,7 @@ public class Example08 {
698
698
699
699
## 4.2 线程的生命周期图
700
700
701
- ![ ] ( http:// img.blog.csdn.net/20150915110410513 )
701
+ ![ ] ( img/thread_17.png )
702
702
703
703
# 挂起状态
704
704
@@ -712,7 +712,7 @@ public class Example08 {
712
712
713
713
(4) 操作系统的需要。操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账。
714
714
715
- ![ ] ( http://i.imgur.com/NHILJar.jpg )
715
+ ![ ] ( img/thread_18.png )
716
716
717
717
加上新建和结束态如下图所示:
718
718
@@ -1105,7 +1105,7 @@ class DeadLockDemo {
1105
1105
1106
1106
运行结果:
1107
1107
1108
- ![ ] ( http:// img.blog.csdn.net/20150810170803595 )
1108
+ ![ ] ( img/thread_20.png )
1109
1109
1110
1110
原因分析:
1111
1111
@@ -1130,7 +1130,7 @@ PS:
1130
1130
1131
1131
- wait和sleep区别?
1132
1132
1133
- ![ ] ( http:// img.blog.csdn.net/20150915105356500 )
1133
+ ![ ] ( img/thread_21.png )
1134
1134
1135
1135
4、为什么操作线程的方法wait、notify、notifyAll定义在了object类中,因为这些方法是监视器的方法,监视器其实就是锁。锁可以是任意的对象,任意的对象调用的方式一定在object类中。
1136
1136
@@ -1239,7 +1239,7 @@ public class StudentDemo {
1239
1239
1240
1240
运行结果:
1241
1241
1242
- ![ ] ( http:// img.blog.csdn.net/20150810173609584 )
1242
+ ![ ] ( img/thread_22.png )
1243
1243
1244
1244
# 8. 线程组
1245
1245
@@ -1319,6 +1319,7 @@ Thread(ThreadGroup group,Runnable target, String name) // 给线程设置分组
1319
1319
- 避免了Java单继承的局限性。所以,创建线程的第二种方式较为常用
1320
1320
1321
1321
## 12.3 线程间的通信
1322
+
1322
1323
- 多个线程在处理同一资源,但是任务却不同,这时候就需要线程间通信。
1323
1324
- 等待/唤醒机制涉及的方法
1324
1325
- wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
@@ -1334,6 +1335,7 @@ Thread(ThreadGroup group,Runnable target, String name) // 给线程设置分组
1334
1335
- sleep必需捕获异常,wait,notify,notifyAll不需要捕获异常
1335
1336
1336
1337
## 12.5 常用方法
1338
+
1337
1339
| 方法声明 | 功能描述 |
1338
1340
| :-------------------------------- | :-------------------- |
1339
1341
| String getName() | 获取线程的名称 |
@@ -1350,4 +1352,5 @@ Thread(ThreadGroup group,Runnable target, String name) // 给线程设置分组
1350
1352
| isInterrupted() | 线程是否被中断 |
1351
1353
1352
1354
## 12.6 线程的生命周期
1353
- 新建,就绪,运行,阻塞(同步阻塞,等待阻塞,其他阻塞),死亡
1355
+
1356
+ 新建,就绪,运行,阻塞(同步阻塞,等待阻塞,其他阻塞),死亡
0 commit comments