##出现原因
当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。
因此引出多线程的三个问题:
1.原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
x = 10; //语句1
y = x; //语句2
x++; //语句3
x = x + 1; //语句4
咋一看,有些朋友可能会说上面的4个语句中的操作都是原子性操作。其实只有语句1是原子性操作,其他三个语句都不是原子性操作。
其他的不多解释,只要是语句2与语句1的不同在于要先去内存中取x的值.
2.可见性:是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
Java为可见性提供了volatile关键字,同时也可以用synchronized和Lock的加锁保证其可见性.
3.有序性:即进程按照程序的语序去执行.
利用这三个关键字都可以一定程度实现程序执行有序性,还有一个机制叫"happens-before".
##volatile关键字
1.双层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
可见性保证每一个线程每次读到都是最新的值,而不能保证其原子性.
public class Test {
public volatile int inc = 0;
public void increase() {
inc++;
}
public static void main(String[] args) {
final Test test = new Test();
for(int i=0;i<10;i++){
new Thread(){
public void run() {
for(int j=0;j<1000;j++)
test.increase();
};
}.start();
}
while(Thread.activeCount()>1) //保证前面的线程都执行完
Thread.yield();
System.out.println(test.inc);
}
}
因此在此例中,返回值会小于10000.
它的禁止指令重排机制可以保证它后面(同时)没有数值需改的操作.
2.原理和机制
摘自《深入理解Java虚拟机》:
“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
3.使用场景
使用要求:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
如:状态标记量和double check.
参考:https://www.cnblogs.com/dolphin0520/p/3920373.html
##synchronized关键字
对于synchronized关键字就不做过多的解释,主要说说它的功能和缺陷.
synchronized 的主要作用为:
1.确保线程互斥访问同步代码
2.共享变量变更能即时可见
3.有效解决重排序问题
synchronized 可修饰:普通方法,静态方法,对象。
缺陷:
一个线程获取资源锁的方式只有等待前一个线程执行完或者是jvm因线程异常而释放资源锁.因此在前一个线程I/O阻塞的情况下就会导致大量线程等待,因此它并不适合于多线程进行大量数据访问的环境中.
##Lock
解决synchronized关键缺陷的方式就是Lock锁,它可以获知线程是否获得锁.
Lock的缺陷在于它并不会去主动的释放锁,因此在释放异常时会造成死锁,使用时应该将其放到异常处理块中.
Lock lock = …;
lock.lock();
try{
//处理任务
}catch(Exception ex){
}finally{
lock.unlock(); //释放锁
}
##总结
在多线程问题中,volatile用于只要求可见性而不用原子性的问题中;synchronized用于少量线程的情况下,不适合用于大量线程和频繁的I/O操作的场景中;Lock 主要是解决了synchronized在大量线程和只读情况下的性能下降问题.
参考:https://www.cnblogs.com/handsomeye/p/5999362.html