北京列举网 > 教育培训 > 电脑/网络 > 拉勾教育Java高并发4解析volatile关键字
北京
[切换城市]

拉勾教育Java高并发4解析volatile关键字

更新时间:2020-11-05 14:39:10 浏览次数:80次
区域: 北京 > 海淀 > 中关村
类别:软件工程师培训
地址:创业大街
1.计算机内部的内存模型
•      我们知道计算机内部含有内存和CPU,那么在进行计算的时候,内存读写还是太慢了,因此在内存和CPU之间还是有一个缓存cache,拉勾IT开发小编为大家分解
•      那么我们知道如果是一个共享变量的话,就会导致,内存中变量和缓存中的变量由于多线程同步不及时,也就是说,一个线程中的缓存还没来的急写入内存,此时有可能在内存中的变量被其他线程读取了。
•      解决这个问题可以:1)通过在总线加LOCK#锁的方式;2)通过缓存一致性协议
•      种方式效率低下,很难实现多线程;第二种方式有一个MSI协议,就是指当缓存写入内存之后,会向其他线程发出信号,共享变量数值已变,如果需要的话,需要重新更新。

2.并发编程的三个概念
•      原子性:一组操作要么全部执行成功,要么全部执行失败,不存在部分成功,部分失败的情况
•      可见性:一个线程对共享变量在缓存中已经更改,但是还没有来得及写入内存,此时又有一个线程访问了该变量,那么就会出现数据不一致
•      有序性:各个语句的执行其实不一定按照从上到下的顺序,但是后个结果一定和按从上到下执行的结果一致,因为如果语句不相干,先执行哪个后执行哪个无所谓,但是语句相干,就会按照从上到下的正常顺序。
3.Java中的内存模型
•      与计算机的内存模型相似,也会有三大特性
•      原子性,这个特性,可以通过synchronnized和lock来保证
•      可见性,Java通过violate来保证,如果共享变量是有violate来修饰那么就是保证,如果改变了它的值就能保证会写入内存之后,别的线程才会调用。
•      有序性,Java中存在happens-before原则来保证有序性,如果两条语句通过该原则仍然不能推断先后执行的先后顺序,那么这两个语句是不是有序的,谁先执行都说不准。
•      程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
•      (1)程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
•      (2)锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作
•      (3)volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
•      (4)传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
•      (5)线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
•      (6)线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
•      (7)线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
•      (8)对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始
4.下面我们举个例子
package com.ruigege.threadFoundation1;

public class TestViolate {
     
     public volatile int inc =1;
     
     
     public static void main(String[] args) {
           TestViolate test = new TestViolate();
     
           for(int i=0;i<10;i++) {
                 //创建十个线程,对inc进行自增操作
                 Thread thread = new Thread(new Runnable() {
                       @Override
                       public void run() {
                             for(int j=0;j<10000;j++) {
                                   tes***c++;
                             }
                       }
                 });
                 thread.start();
           }
           
           while(Thread.activeCount()>1) {
                 Thread.yield();//如果存在还没有结束的线程,就需要尽量让出CPU供它们运行
           }
           System.out.println(tes***c);
     }
     
}
•      我们将这段代码运行三次
•      这结果和我们预想的不一样,为什么呢?
北京电脑/网络相关信息
办公软件培训
平谷-平谷城区
9月2日
4月23日
办公软件培训
平谷-平谷城区
4月19日
办公软件培训
平谷-平谷城区
4月11日
办公软件培训
平谷-平谷城区
4月9日
注册时间:2020年08月20日
UID:706755
---------- 认证信息 ----------
手机已认证
查看用户主页