1- [ TOC]
2-
3- <!-- TOC -->
4-
5- - [ 并发编程] ( #并发编程 )
6- - [ 1. 线程状态转换] ( #1-线程状态转换 )
7- - [ 新建(New)] ( #新建new )
8- - [ 可运行(Runnable)] ( #可运行runnable )
9- - [ 阻塞(Blocking)] ( #阻塞blocking )
10- - [ 无限期等待(Waiting)] ( #无限期等待waiting )
11- - [ 限期等待(Timed Waiting)] ( #限期等待timed-waiting )
12- - [ 死亡(Terminated)] ( #死亡terminated )
13- - [ 2. Java实现多线程的方式及三种方式的区别【阿里面经Onenote】] ( #2-java实现多线程的方式及三种方式的区别阿里面经onenote )
14- - [ 实现 Runnable 接口] ( #实现-runnable-接口 )
15- - [ 实现 Callable 接口] ( #实现-callable-接口 )
16- - [ 继承 Thread 类] ( #继承-thread-类 )
17- - [ 实现接口 VS 继承 Thread] ( #实现接口-vs-继承-thread )
18- - [ 3. 基础线程机制:什么是守护线程、等待线程、礼让线程、线程阻塞?] ( #3-基础线程机制什么是守护线程等待线程礼让线程线程阻塞 )
19- - [ Daemon(守护线程)] ( #daemon守护线程 )
20- - [ Executor] ( #executor )
21- - [ sleep()] ( #sleep )
22- - [ yield()] ( #yield )
23- - [ 线程阻塞] ( #线程阻塞 )
24- - [ 4. 线程间的协作(信息交互)【阿里面经Onenote】] ( #4-线程间的协作信息交互阿里面经onenote )
25- - [ join()] ( #join )
26- - [ wait() notify() notifyAll()] ( #wait-notify-notifyall )
27- - [ await() signal() signalAll()] ( #await-signal-signalall )
28- - [ sleep和wait分别是那个类的方法,有什么区别【阿里面经Onenote】] ( #sleep和wait分别是那个类的方法有什么区别阿里面经onenote )
29- - [ 5. 互斥同步] ( #5-互斥同步 )
30- - [ synchronized] ( #synchronized )
31- - [ ReentrantLock] ( #reentrantlock )
32- - [ synchronized 和 ReentrantLock 比较] ( #synchronized-和-reentrantlock-比较 )
33- - [ synchronized与lock的区别,使用场景。看过synchronized的源码没?【阿里面经Onenote】] ( #synchronized与lock的区别使用场景看过synchronized的源码没阿里面经onenote )
34- - [ 什么是乐观锁和悲观锁] ( #什么是乐观锁和悲观锁 )
35- - [ synchronized底层如何实现的?用在代码块和方法上有什么区别?] ( #synchronized底层如何实现的用在代码块和方法上有什么区别 )
36- - [ 6. Java 内存模型(JMM)] ( #6-java-内存模型jmm )
37- - [ 主内存与工作内存] ( #主内存与工作内存 )
38- - [ 内存间交互操作] ( #内存间交互操作 )
39- - [ 内存模型三大特性] ( #内存模型三大特性 )
40- - [ volatile 与synchronized 的区别] ( #volatile-与synchronized-的区别 )
41- - [ 7. 什么是线程池?如果让你设计一个动态大小的线程池,如何设计,应该有哪些方法?线程池创建的方式?【阿里面经Onenote】] ( #7-什么是线程池如果让你设计一个动态大小的线程池如何设计应该有哪些方法线程池创建的方式阿里面经onenote )
42- - [ 8. 什么是并发和并行] ( #8-什么是并发和并行 )
43- - [ 9. 什么是线程安全【阿里面经Onenote】] ( #9-什么是线程安全阿里面经onenote )
44- - [ 非线程安全!=不安全?] ( #非线程安全不安全 )
45- - [ 线程安全十万个为什么?] ( #线程安全十万个为什么 )
46- - [ 10. 什么是死锁?死锁的四个必要条件?] ( #10-什么是死锁死锁的四个必要条件 )
47- - [ 什么是死锁] ( #什么是死锁 )
48- - [ 死锁的四个必要条件] ( #死锁的四个必要条件 )
49- - [ 处理死锁的策略] ( #处理死锁的策略 )
50- - [ 死锁预防] ( #死锁预防 )
51- - [ 死锁避免] ( #死锁避免 )
52- - [ 11. volatile 关键字的如何保证内存可见性【阿里面经Onenote】] ( #11-volatile-关键字的如何保证内存可见性阿里面经onenote )
53- - [ 12. 什么是线程?线程和进程有什么区别?为什么要使用多线程【阿里面经Onenote】] ( #12-什么是线程线程和进程有什么区别为什么要使用多线程阿里面经onenote )
54- - [ 13. 多线程共用一个数据变量需要注意什么?【阿里面经Onenote】] ( #13-多线程共用一个数据变量需要注意什么阿里面经onenote )
55- - [ 14. Java是否有内存泄露和内存溢出【阿里面经Onenote】] ( #14-java是否有内存泄露和内存溢出阿里面经onenote )
56- - [ ] ( # )
57- - [ 15. 线程间通信和进程间通信?] ( #15-线程间通信和进程间通信 )
58- - [ 进程间通信] ( #进程间通信 )
59- - [ 进程间通信] ( #进程间通信-1 )
60- - [ 16. 什么是同步和异步,阻塞和非阻塞?] ( #16-什么是同步和异步阻塞和非阻塞 )
61- - [ 同步] ( #同步 )
62- - [ 异步] ( #异步 )
63- - [ 阻塞] ( #阻塞 )
64- - [ 非阻塞] ( #非阻塞 )
65- - [ 17. 并发包(待完善)] ( #17-并发包待完善 )
66- - [ 附录:参考资料] ( #附录参考资料 )
67-
68- <!-- /TOC -->
69-
70- ## 并发编程
71-
72- ### 1. 线程状态转换
73-
74- [ ![ img] ( https://github.com/CyC2018/Interview-Notebook/raw/master/pics/ace830df-9919-48ca-91b5-60b193f593d2.png )] ( https://github.com/CyC2018/Interview-Notebook/blob/master/pics/ace830df-9919-48ca-91b5-60b193f593d2.png )
1+
2+
3+ # 前言
4+
5+ 在本文将总结多线程并发编程中的常见面试题,主要核心线程生命周期、线程通信、并发包部分。
6+
7+
8+
9+ 参考资料:
10+
11+ - 《Java并发编程实战》
12+ - 【慕课网】Java并发编程与高并发解决方案
13+
14+
15+
16+ # 并发编程
17+
18+ ## 1. 线程状态转换
19+
20+ <div align =" center " > <img src =" https://github.com/CyC2018/Interview-Notebook/raw/master/pics/ace830df-9919-48ca-91b5-60b193f593d2.png " width =" " /></div ><br />
21+
22+
7523
7624#### 新建(New)
7725
12674
12775
12876
129- ### 2. Java实现多线程的方式及三种方式的区别【阿里面经Onenote】
77+ ## 2. Java实现多线程的方式及三种方式的区别【阿里面经Onenote】
13078
13179- 实现多线程的方式
13280
@@ -220,9 +168,11 @@ public static void main(String[] args) {
220168
221169
222170
223- ### 3. 基础线程机制:什么是守护线程、等待线程、礼让线程、线程阻塞?
171+ ## 3. 基础线程机制:什么是守护线程、等待线程、礼让线程、线程阻塞?
172+
173+ <div align =" center " > <img src =" ../pics/thread_status.jpg " width =" " /></div ><br />
174+
224175
225- ![ ] ( ../pics/thread_status.jpg )
226176
227177#### Daemon(守护线程)
228178
@@ -311,7 +261,7 @@ public void run() {
311261
312262
313263
314- ### 4. 线程间的协作(信息交互)【阿里面经Onenote】
264+ ## 4. 线程间的协作(信息交互)【阿里面经Onenote】
315265
316266当多个线程可以一起工作去解决某个问题时,如果某些部分必须在其它部分之前完成,那么就需要对线程进行协调。
317267
@@ -486,7 +436,7 @@ after
486436
487437
488438
489- ### 5. 互斥同步
439+ ## 5. 互斥同步
490440
491441Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLock。
492442
@@ -730,7 +680,7 @@ ReentrantLock 多了一些高级功能。
730680
731681
732682
733- ### 6. Java 内存模型(JMM)
683+ ## 6. Java 内存模型(JMM)
734684
735685Java 内存模型试图屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。
736686
@@ -740,23 +690,25 @@ Java 内存模型试图屏蔽各种硬件和操作系统的内存访问差异,
740690
741691加入高速缓存带来了一个新的问题:缓存一致性。如果多个缓存共享同一块主内存区域,那么多个缓存的数据可能会不一致,需要一些协议来解决这个问题。
742692
743- [ ![ img] ( https://github.com/CyC2018/Interview-Notebook/raw/master/pics/68778c1b-15ab-4826-99c0-3b4fd38cb9e9.png )] ( https://github.com/CyC2018/Interview-Notebook/blob/master/pics/68778c1b-15ab-4826-99c0-3b4fd38cb9e9.png )
693+ <div align =" center " > <img src =" https://github.com/CyC2018/Interview-Notebook/raw/master/pics/68778c1b-15ab-4826-99c0-3b4fd38cb9e9.png " width =" " /></div ><br />
694+
695+
744696
745697所有的变量都存储在主内存中,每个线程还有自己的工作内存,工作内存存储在高速缓存或者寄存器中,保存了该线程使用的变量的主内存副本拷贝。
746698
747699线程只能直接操作工作内存中的变量,不同线程之间的变量值传递需要通过主内存来完成。
748700
749- [ ![ img] ( https://github.com/CyC2018/Interview-Notebook/raw/master/pics/47358f87-bc4c-496f-9a90-8d696de94cee.png )] ( https://github.com/CyC2018/Interview-Notebook/blob/master/pics/47358f87-bc4c-496f-9a90-8d696de94cee.png )
701+ < div align = " center " > < img src = " https://github.com/CyC2018/Interview-Notebook/raw/master/pics/47358f87-bc4c-496f-9a90-8d696de94cee.png " width = " 600 " /></ div >< br />
750702
751703
752704
753-
754-
755705#### 内存间交互操作
756706
757707Java 内存模型定义了 8 个操作来完成主内存和工作内存的交互操作。
758708
759- ![ ] ( ../pics/jmm_opt-8.png )
709+ <div align =" center " > <img src =" ../pics/jmm_opt-8.png " width =" 700 " /></div ><br />
710+
711+
760712
761713
762714
@@ -842,7 +794,7 @@ synchronized不仅保证可见性,而且还保证原子性,因为,只有
842794
843795
844796
845- ### 7. 什么是线程池?如果让你设计一个动态大小的线程池,如何设计,应该有哪些方法?线程池创建的方式?【阿里面经Onenote】
797+ ## 7. 什么是线程池?如果让你设计一个动态大小的线程池,如何设计,应该有哪些方法?线程池创建的方式?【阿里面经Onenote】
846798
847799- 什么是线程池
848800
@@ -879,22 +831,24 @@ synchronized不仅保证可见性,而且还保证原子性,因为,只有
879831
880832
881833
882- ### 8. 什么是并发和并行
834+ ## 8. 什么是并发和并行
883835
884836- 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行。(需要多核CPU)
885837- 并发是指两个任务都请求运行,而处理器只能按受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行。
886838- 比如我跟两个网友聊天,左手操作一个电脑跟甲聊,同时右手用另一台电脑跟乙聊天,这就叫并行。
887839- 如果用一台电脑我先给甲发个消息,然后立刻再给乙发消息,然后再跟甲聊,再跟乙聊。这就叫并发。
888840
889- ![ ] ( D:/gitdoc/2019_campus_appy/notes/pics/concurrent_and_parallel.png )
841+ <div align =" center " > <img src =" ../pics/concurrent_and_parallel.png " width =" " /></div ><br />
842+
843+
890844
891845参考资料:
892846
893847- [ Cplusplus-Concurrency-In-Practice/1.1 What is concurrency.md at master · forhappy/Cplusplus-Concurrency-In-Practice] ( https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter1-Introduction/1.1%20What%20is%20concurrency.md )
894848
895849
896850
897- ### 9. 什么是线程安全【阿里面经Onenote】
851+ ## 9. 什么是线程安全【阿里面经Onenote】
898852
899853当多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替运行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获取正确的结果,那这个对象是线程安全的。——来自《深入理解Java虚拟机》
900854
@@ -956,7 +910,7 @@ synchronized不仅保证可见性,而且还保证原子性,因为,只有
956910
957911
958912
959- ### 10. 什么是死锁?死锁的四个必要条件?
913+ ## 10. 什么是死锁?死锁的四个必要条件?
960914
961915#### 什么是死锁
962916
@@ -1012,7 +966,7 @@ synchronized不仅保证可见性,而且还保证原子性,因为,只有
1012966
1013967
1014968
1015- ### 11. volatile 关键字的如何保证内存可见性【阿里面经Onenote】
969+ ## 11. volatile 关键字的如何保证内存可见性【阿里面经Onenote】
1016970
1017971- volatile 关键字的作用
1018972
@@ -1056,7 +1010,7 @@ synchronized不仅保证可见性,而且还保证原子性,因为,只有
10561010
10571011
10581012
1059- ### 12. 什么是线程?线程和进程有什么区别?为什么要使用多线程【阿里面经Onenote】
1013+ ## 12. 什么是线程?线程和进程有什么区别?为什么要使用多线程【阿里面经Onenote】
10601014
10611015(1)线程和进程
10621016
@@ -1074,13 +1028,13 @@ synchronized不仅保证可见性,而且还保证原子性,因为,只有
10741028
10751029
10761030
1077- ### 13. 多线程共用一个数据变量需要注意什么?【阿里面经Onenote】
1031+ ## 13. 多线程共用一个数据变量需要注意什么?【阿里面经Onenote】
10781032
10791033- 当我们在线程对象(Runnable)中定义了全局变量,run方法会修改该变量时,如果有多个线程同时使用该线程对象,那么就会造成全局变量的值被同时修改,造成错误.
10801034- ThreadLocal是JDK引入的一种机制,它用于解决线程间共享变量,使用ThreadLocal声明的变量,即使在线程中属于全局变量,针对每个线程来讲,这个变量也是独立的。
10811035- volatile变量每次被线程访问时,都强迫线程从主内存中重读该变量的最新值,而当该变量发生修改变化时,也会强迫线程将最新的值刷新回主内存中。这样一来,不同的线程都能及时的看到该变量的最新值。
10821036
1083- ### 14. Java是否有内存泄露和内存溢出【阿里面经Onenote】
1037+ ## 14. Java是否有内存泄露和内存溢出【阿里面经Onenote】
10841038
10851039- 静态集合类,使用Set、Vector、HashMap等集合类的时候需要特别注意。当这些类被定义成静态的时候,由于他们的生命周期跟应用程序一样长,这时候就有可能发生内存泄漏。
10861040
@@ -1121,7 +1075,7 @@ public void register(Object o)
11211075
11221076###
11231077
1124- ### 15. 线程间通信和进程间通信?
1078+ ## 15. 线程间通信和进程间通信?
11251079
11261080#### 线程间通信
11271081
@@ -1165,7 +1119,7 @@ public void register(Object o)
11651119
11661120
11671121
1168- ### 16. 什么是同步和异步,阻塞和非阻塞?
1122+ ## 16. 什么是同步和异步,阻塞和非阻塞?
11691123
11701124
11711125
@@ -1203,7 +1157,7 @@ public void register(Object o)
12031157
12041158
12051159
1206- ### 17. 并发包(非常重要!!!待整理)
1160+ ## 17. 并发包(非常重要!!!待整理)
12071161
12081162#### concurrenthashmap分段锁的细节?【蚂蚁金服面经】
12091163
0 commit comments