ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

并发的三大特性 -- java面试

2021-09-11 16:30:02  阅读:198  来源: 互联网

标签:java 变量 synchronized -- stop 线程 内存 volatile 三大


原子性

原子性是指在一个操作中,cpu不能在中途暂停然后再调度,即不被中断操作,要么全部执行完成,要么全部不执行。

例子:

private long count = 0;
public void calc() {
    count++;
}
  1. 将count从主内存读到工作内存的副本中
  2. 对工作内存的count+1运算
  3. 将结果写入工作内存
  4. 将工作内存的值写入主内存

count++并不是原子操作,它包含了多个步骤。在多线程中,可能一个线程正在自增操作,另一个线程就已经读取了值,就会导致结果错误。那如果能保证自增操作是一个原子性的操作,那么就能保证其他进程读取的是递增后的数据。

可以使用synchronized解决。

可见性

可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改后的值。

当一个线程改变了i的值还没刷新到主内存,线程2又读取了i的值,那么这个i值还是以前的,线程2没有看到线程1对变量的修改,这就是可见性问题。

//线程1
boolean stop = false; 
while(!stop){
    doSomething();
}
//线程2
stop = true;

假如在线程2改变了stop变量的值后,还没来得及写入主内存中就转去做其他事情了,那么线程1因为看不到stop变量的更改,会继续循环。

可以使用volatile、synchronized、final解决。


volatile解决问题:

//线程1
volatile boolean stop = false; 
while(!stop){
    doSomething();
}
//线程2
stop = true;
  1. 使用volatile关键字会强制将修改的值立即写入主内存。

  2. 当线程2进行修改时,会导致线程1的工作内存中的缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效)。

  3. 由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1会再次会去主内存读取stop变量。这样线程1就可以正常关闭了。

有序性

虚拟机在编译时,对于那些改变顺序不影响结果的代码,虚拟机不一定按照我们编写代码的顺序来执行,有可能对它们进行重排序,这可能会出现线程安全问题。

int a = 0;
bool flag = false;
public void write() {
    a = 2;              //1
    flag = true;        //2
}
public void multiply() {
    if (flag) {         //3
        int ret = a * a;//4
} }

假设线程1执行write()方法,线程2执行multipy()方法

假如在write()方法中对1和2做了重排序,线程1先将flag设置为true,随后线程2执行语句3和4,那么ret就是0,这时候线程1继续运行,这才将a赋值2,很明显迟了一步,与预计结果的ret=4不符合。

可以使用volatile、synchronized解决。

synchronized和volatile

synchronized关键字同时满足以上三种特性,但是volatile关键字不满足原子性。

在某些情况下,volatile的同步机制的性能优于锁(使用synchronized关键字或java.util.concurrent),因为volatile的总开销要比锁低。

判断使用volatile还是加锁的依据是:volatile的语义能否满足使用的场景。

volatile作用

  1. 保证volatile修饰的共享变量对所有线程总是可见,也就是当一个线程修改这个变量,新值总是可以被其他线程立即得知。

  2. 禁止指令重排序。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置)。

标签:java,变量,synchronized,--,stop,线程,内存,volatile,三大
来源: https://blog.csdn.net/qq_34626094/article/details/120237700

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有