Skip to content

Commit

Permalink
完善Java并发
Browse files Browse the repository at this point in the history
  • Loading branch information
Dynamicboboo committed Jul 1, 2020
1 parent 5acb55c commit 5a909e2
Showing 1 changed file with 60 additions and 1 deletion.
61 changes: 60 additions & 1 deletion Java并发编程.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,69 @@ new Thread(){

### 13.能从JAVA底层角度聊聊volatile关键字的原理么?

**volatile关键字的两层语义**

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

2)禁止进行指令重排序。

如果直接问volatile关键字,想要解释清楚的话,要从Java内存模型开始讲起。

volatile关键字是用来解决可见性和有序性问题,在有些罕见的条件下,可以有限的保证原子性。
但是它主要不是用来保证原子性的。

volatile保证可见性的原理,如果多个线程操作一个被volatile修饰的变量,当其中一个线程成功对组内存中的数据完成修改以后,它会将其他线程工作内存中的该变量的数据设为失效状态,迫使其它线程重新从主内存中读取变量数据,从而实现有可见性。

在很多的开源中间件系统的源码里,大量的使用了volatile。常常使用的一个场景是对于一个变量,有的线程要更新它有的线程要读取它来进行判断操作,这个时候就需要使用volatile关键字,来保证读取到最新的数据。

### 14你知道指令重排、内存栅栏以及happens-before这些是什么?

Java内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,这个通常也称为 happens-before 原则。如果两个操作的执行次序无法从happens-before原则推导出来,那么它们就不能保证它们的有序性,虚拟机可以随意地对它们进行重排序。

1.程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作。
2、锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。

3、volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个volatile变量的读操作。必须保证先写再读。

4、传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,那么可以得出操作A
先行发生于操作C。
5、线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作。
6、线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断时间的发生。
7、线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测现场是否已经终止执行
8、对象终结规则:一个对象的初始完成先行发生于他的finalize()方法的开始。
**规则制定了一些特殊情况下,不允许编译器、指令器对我们写的代码进行指令重排,必须保证代码的有序性可用以上八种方法+volatile**

### 15.volatile底层是如何基于内存屏障保证可见性和有序性的?

### 16.能说说ThreadLocal的底层实现原理么?
volatile+原子性:不能够保证原子性,只有在一些极端情况下能保证原子性。

保证原子性:synchronized,lock,加锁。

(1)lock指令:volatile保证可见性

```tex
对volatile修饰的变量,执行写操作的话,JVM会发送一条lock前缀指令给CPU,CPU在计算完后会立即将这个值写回主内存,同时因为MESI缓存一致性协议,所以各个CPU都会对总线进行嗅探,自己本地缓存中的数据是否被修改了。
如果发现被修改了,那么CPU就会将自己的本地缓存数据过期掉,然后从主内存中重新加载最新的数据。
```

(2)内存屏障:禁止重排序

并发这一块的知识非常的深,synchronized、volatile,的层都对应着一套复杂的cpu级别的硬件原理,大量的内存屏障原理;lock API,concurrentHashmap,都是各种复杂的jdk级别的源码。如果有时间可以自己多花时间买书看。

### 16. 能说说ThreadLocal的底层实现原理么?

### **17. java中异常分为哪两种?**

编译时异常、运行时异常

**Error与Exception区别?**

Error和Exception都是java错误处理机制的一部分,都继承了Throwable类。
Exception表示的异常,异常可以通过程序来捕捉,或者优化程序来避免。
Error表示的是系统错误,不能通过程序来进行错误处理。

Exception又包含了运行时异常(RuntimeException, 又叫非检查异常)和非运行时异常(又叫检查异常)

0 comments on commit 5a909e2

Please sign in to comment.