diff --git a/docs/java/Multithread/JavaConcurrencyAdvancedCommonInterviewQuestions.md b/docs/java/Multithread/JavaConcurrencyAdvancedCommonInterviewQuestions.md index 2e983aa546a104b1939e4abc8e7d7cff409ba70e..7a692cf192c2972130298e08681007982184f33c 100644 --- a/docs/java/Multithread/JavaConcurrencyAdvancedCommonInterviewQuestions.md +++ b/docs/java/Multithread/JavaConcurrencyAdvancedCommonInterviewQuestions.md @@ -186,10 +186,15 @@ synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团 ![volatile关键字的可见性](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/volatile关键字的可见性.png) +### 2.2 并发编程的三个重要特性 -### 2.2. 说说 synchronized 关键字和 volatile 关键字的区别 +1. **原子性** : 一个的操作或者多次操作,要么所有的操作全部都得到执行并且不会收到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。`synchronized ` 可以保证代码片段的原子性。 +2. **可见性** :当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。`volatile` 关键字可以保证共享变量的可见性。 +3. **有序性** :代码在执行的过程中的先后顺序,Java 在编译器以及运行期间的优化,代码的执行顺序未必就是编写代码时候的顺序。`volatile` 关键字可以禁止指令进行重排序优化。 - synchronized关键字和volatile关键字比较 +### 2.3. 说说 synchronized 关键字和 volatile 关键字的区别 + +`synchronized` 关键字和 `volatile` 关键字是两个互补的存在,而不是对立的存在: - **volatile关键字**是线程同步的**轻量级实现**,所以**volatile性能肯定比synchronized关键字要好**。但是**volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块**。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,**实际开发中使用 synchronized 关键字的场景还是更多一些**。 - **多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞** diff --git a/docs/java/Multithread/JavaConcurrencyBasicsCommonInterviewQuestionsSummary.md b/docs/java/Multithread/JavaConcurrencyBasicsCommonInterviewQuestionsSummary.md index 030c48004d326ce8d1b5afb4e2853106e504d913..a280bd8c5d97050a92bb1d3e9d4f7d7cdda08db5 100644 --- a/docs/java/Multithread/JavaConcurrencyBasicsCommonInterviewQuestionsSummary.md +++ b/docs/java/Multithread/JavaConcurrencyBasicsCommonInterviewQuestionsSummary.md @@ -165,7 +165,7 @@ Linux 相比与其他操作系统(包括其他类 Unix 系统)有很多的 ### 8.1. 认识线程死锁 -多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 +线程死锁描述的是这样一种情况:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。 @@ -232,23 +232,12 @@ Thread[线程 2,5,main]waiting get resource1 ### 8.2. 如何避免线程死锁? -我们只要破坏产生死锁的四个条件中的其中一个就可以了。 +我上面说了产生死锁的四个必要条件,为了避免死锁,我们只要破坏产生死锁的四个条件中的其中一个就可以了。现在我们来挨个分析一下: -**破坏互斥条件** - -这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。 - -**破坏请求与保持条件** - -一次性申请所有的资源。 - -**破坏不剥夺条件** - -占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。 - -**破坏循环等待条件** - -靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。 +1. **破坏互斥条件** :这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。 +2. **破坏请求与保持条件** :一次性申请所有的资源。 +3. **破坏不剥夺条件** :占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。 +4. **破坏循环等待条件** :靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。 我们对线程 2 的代码修改成下面这样就不会产生死锁了。