Skip to content

Commit b31c1aa

Browse files
committed
updates
1 parent 4ddc21f commit b31c1aa

14 files changed

+17
-14
lines changed

第5章 多线程/img/thread_09.png

67 KB
Loading

第5章 多线程/img/thread_12.png

11.4 KB
Loading

第5章 多线程/img/thread_15.png

27.9 KB
Loading

第5章 多线程/img/thread_17.png

74.7 KB
Loading

第5章 多线程/img/thread_18.png

32.5 KB
Loading

第5章 多线程/img/thread_20.png

14.4 KB
Loading

第5章 多线程/img/thread_21.png

17.5 KB
Loading

第5章 多线程/img/thread_22.png

15.3 KB
Loading

第5章 多线程/多线程.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ typora-copy-images-to: img
88

99
## 1.1 多线程引入
1010

11-
![](http://img.blog.csdn.net/20150827214823243)
11+
![](img/thread_09.png)
1212

1313
由上图中程序的调用流程可知,这个程序只有一个执行流程,所以这样的程序就是单线程程序。假如一个程序有多条执行流程,那么,该程序就是多线程程序。
1414

@@ -21,7 +21,7 @@ typora-copy-images-to: img
2121
在一个操作系统中,每个独立执行的程序都可称之为一个进程,也就是“正在运行的程序”。目前大部分计算机上安装的都
2222
是多任务操作系统,即能够同时执行多个应用程序,最常见的有Windows、Linux、Unix等。在本教材使用的Windows操作系统下,鼠标右键单击任务栏,选择【启动任务管理器】选项可以打开任务管理器面板,在窗口的【进程】选项卡中可以看到当前正在运行的程序,也就是系统所有的进程,如chrome.exe、QQ.exe等。任务管理器的窗口如图所示。
2323

24-
![1500693373975](img/1500693373975.png)
24+
![多线程](img/thread_10.png)
2525

2626
在多任务操作系统中,表面上看是支持进程并发执行的,例如可以一边听音乐一边聊天。但实际上这些进程并不是同时运行的。在计算机中,所有的应用程序都是由CPU执行的,对于一个CPU而言,在某个时间点只能运行一个程序,也就是说只能执行一个进程。操作系统会为每一个进程分配一段有限的CPU使用时间,CPU在这段时间中执行某个进程,然后会在下一段时间切换到另一个进程中去执行。由于CPU运行速度很快,能在极短的时间内在不同的进程之间进行切换,所以给人以同时执行多个程序的感觉。
2727

@@ -41,7 +41,7 @@ typora-copy-images-to: img
4141

4242
多线程程序的执行过程如图所示
4343

44-
![1500693584730](img/1500693584730.png)
44+
![thread](img/thread_11.png)
4545

4646
图中所示的多条线程,看似是同时执行的,其实不然,它们和进程一样,也是由CPU轮流执行的,只不过CPU运行速度很快,故而给人同时执行的感觉。
4747

@@ -312,7 +312,7 @@ public class CallableDemo {
312312

313313
运行结果:
314314

315-
![](http://img.blog.csdn.net/20150810174959628)
315+
![](img/thread_12.png)
316316

317317

318318
实现Callable的优缺点
@@ -343,7 +343,7 @@ new Thread(new Runnable() {
343343

344344
## 2.5 单线程和多线程的运行流程
345345

346-
![1500693721559](img/1500693721559.png)
346+
![thread](img/thread_13.png)
347347

348348
从图可以看出,单线程的程序在运行时,会按照代码的调用顺序执行,而在多线程中,main()方法和MyThread类的run()方法却可以同时运行,互不影响,这正是单线程和多线程的区别。
349349

@@ -369,7 +369,7 @@ Java使用的是抢占式调度模型。
369369

370370
在应用程序中,如果要对线程进行调度,最直接的方式就是设置线程的优先级。优先级越高的线程获得CPU执行的机会越大,而优先级越低的线程获得CPU执行的机会越小。线程的优先级用1~10之间的整数来表示,数字越大优先级越高。除了可以直接使用数字表示线程的优先级,还可以使用Thread类中提供的三个静态常量表示线程的优先级,如表所示。
371371

372-
![1500694154099](img/1500694154099.png)
372+
![thread](img/thread_14.png)
373373

374374
程序在运行期间,处于就绪状态的每个线程都有自己的优先级,例如main线程具有普通优先级。然而线程优先级不是固定不变的,可以通过Thread类的setPriority(int newPriority)方法对其进行设置,该方法中的参数newPriority接收的是1~10之间的整数或者Thread类的三个静态常量。
375375

@@ -646,13 +646,13 @@ public class Example08 {
646646

647647
三种状态的切换如下图所示:
648648

649-
![](http://i.imgur.com/xxOWT2V.jpg)
649+
![](img/thread_15.png)
650650

651651
# 4. 线程的生命周期
652652

653653
在Java中,任何对象都有生命周期,线程也不例外,它也有自己的生命周期。当Thread对象创建完成时,线程的生命周期便开始了。当run()方法中代码正常执行完毕或者线程抛出一个未捕获的异常(Exception)或者错误(Error)时,线程的生命周期便会结束。线程整个生命周期可以分为五个阶段,分别是新建状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)和死亡状态(Terminated),线程的不同状态表明了线程当前正在进行的活动。在程序中,通过一些操作,可以使线程在不同状态之间转换,如图所示。
654654

655-
![1500693803598](img/1500693803598.png)
655+
![thread](img/thread_16.png)
656656

657657
图中展示了线程各种状态的转换关系,箭头表示可转换的方向,其中,单箭头表示状态只能单向的转换,例如线程只能从新建状态转换到就绪状态,反之则不能;双箭头表示两种状态可以互相转换,例如就绪状态和运行状态可以互相转换。通过一张图还不能完全描述清楚线程各状态之间的区别,接下来针对线程生命周期中的五种状态分别进行详细讲解,具体如下:
658658

@@ -698,7 +698,7 @@ public class Example08 {
698698

699699
## 4.2 线程的生命周期图
700700

701-
![](http://img.blog.csdn.net/20150915110410513)
701+
![](img/thread_17.png)
702702

703703
# 挂起状态
704704

@@ -712,7 +712,7 @@ public class Example08 {
712712

713713
(4) 操作系统的需要。操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账。
714714

715-
![](http://i.imgur.com/NHILJar.jpg)
715+
![](img/thread_18.png)
716716

717717
加上新建和结束态如下图所示:
718718

@@ -1105,7 +1105,7 @@ class DeadLockDemo {
11051105

11061106
运行结果:
11071107

1108-
![](http://img.blog.csdn.net/20150810170803595)
1108+
![](img/thread_20.png)
11091109

11101110
原因分析:
11111111

@@ -1130,7 +1130,7 @@ PS:
11301130

11311131
- wait和sleep区别?
11321132

1133-
![](http://img.blog.csdn.net/20150915105356500)
1133+
![](img/thread_21.png)
11341134

11351135
4、为什么操作线程的方法wait、notify、notifyAll定义在了object类中,因为这些方法是监视器的方法,监视器其实就是锁。锁可以是任意的对象,任意的对象调用的方式一定在object类中。
11361136

@@ -1239,7 +1239,7 @@ public class StudentDemo {
12391239

12401240
运行结果:
12411241

1242-
![](http://img.blog.csdn.net/20150810173609584)
1242+
![](img/thread_22.png)
12431243

12441244
# 8. 线程组
12451245

@@ -1319,6 +1319,7 @@ Thread(ThreadGroup group,Runnable target, String name) // 给线程设置分组
13191319
- 避免了Java单继承的局限性。所以,创建线程的第二种方式较为常用
13201320

13211321
## 12.3 线程间的通信
1322+
13221323
- 多个线程在处理同一资源,但是任务却不同,这时候就需要线程间通信。
13231324
- 等待/唤醒机制涉及的方法
13241325
- wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
@@ -1334,6 +1335,7 @@ Thread(ThreadGroup group,Runnable target, String name) // 给线程设置分组
13341335
- sleep必需捕获异常,wait,notify,notifyAll不需要捕获异常
13351336

13361337
## 12.5 常用方法
1338+
13371339
| 方法声明 | 功能描述 |
13381340
| :-------------------------------- | :-------------------- |
13391341
| String getName() | 获取线程的名称 |
@@ -1350,4 +1352,5 @@ Thread(ThreadGroup group,Runnable target, String name) // 给线程设置分组
13501352
| isInterrupted() | 线程是否被中断 |
13511353

13521354
## 12.6 线程的生命周期
1353-
新建,就绪,运行,阻塞(同步阻塞,等待阻塞,其他阻塞),死亡
1355+
1356+
新建,就绪,运行,阻塞(同步阻塞,等待阻塞,其他阻塞),死亡

0 commit comments

Comments
 (0)