A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始


1.JMM

​     什么是JMM

​     JMM(Java内存模型 Java Memory Model 简称JMM) 本身是一种抽象的概念,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量的访问方式

​       由于JVM运行程序的实体是线程,而每个线程创建JVM 都会为其创建一个工作内存,工作内存是每个线程的私有数据区域,而Java内存模型规定中的变量都存储在主内存,主内存是共享数据,所有线程都能访问,但线程对变量的操作(读写值)都必须在工作内存中完成->简单说,就是先读取,再操作,再写回,工作内存存放的是主内存中的副本,线程的通信都需要通过主内存来完成

内存可见性 :工作内存之间彼此内存不可见

如何解决呢?



多线程什么情况下会触发安全问题?

​                  1.当多个线程在操作同一个共享数据时,就有可能会发生线程安全问题

2.Volatile

​                  volatile 是什么?

​                                    轻量级的同步方案

​                    1.volatile 可以解决内存可见性问题     syn解决内存可见问题



​                                        2.volatile 关键不能解决原子性问题

​                                                                原子性问题:要么都成功,要么都失败   

​                                                            count++   



​                                        3.volatile禁止了重排序

3. 什么是指令重排

是什么?

  编译器在不改变运行结果的情况下,按照自己的喜好对指令进行重排,重排的效果是提高代码运行效率

因为Java指定了一套规则,在这套规则下,默认不能进行指令重排

​                         happend-before    8个条件

~~~java
main(){
            

```
int i =10;  //1
int j =20;  //2
int flag = true; //3
sop(i,j,flag)
```

}

多线程模型重排序
class JmmExample{
         private boolean flag = false;
         int i =5;
         int j =5;
         

```
read(){
        i =10;                 //1
        j =20;       //2
        flag =true;  // 3
}
```

    write(){
      while(flag){
                      int temp = i * j;  // 10 * 20 = 200   5 * 5 = 25
             }       
      }
}



3.1  悲观锁和乐观锁

乐观锁:制定了一个版本号,每次操作这个数据,对应版本号+1 ,提交数据时,要比安全的数据版本号大一,否则提交失败



悲观锁:

​                   读锁/ 共享锁    只要是读的线程都能获得这把锁 -> 读时不会触发安全问题

​                   写锁/ 排他锁    一个人持有锁,其他人都不能够拿到锁  



4.Cas



cas 是什么

   比较并替换   

   类似于乐观锁



cas  --> 快  ->安全

​                         快: unsafe 类-->系统底层类 -->拥有C 一样的指针直接去操作内存

​                         安全:系统原语 --> 一旦完成了  compare  相等--> 那就不可分割



底层原理:

​                  unsafe 类: rt.jar 包下的类容   sun.misc

​                 1.Unsafe 类:

​           是CAS 的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,

Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据,Unsafe 类存在于sun.misc包中,其内部方法可以像操作C的指针一样去直接操作内存,因为Java中CAS操作的执行依赖于Unsafe类的方法

​     Unsafe类中的方法都是native修饰的,也就是说Unsafe类中的方法都直接调用了操作系统底层资源执行任务
                                                                       
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);// var1: this var2  内存偏移量  var4:修改值
        //主内存中的数据-->  在这个偏移量上对应的这个对象的volatile 修饰的值
        
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
                        //模拟一个成功
                        //  将主内存中的这个值 加上var4     如果修改成功 true -> !true -> false
                        //  如果比较失败-> false  ->! false -> true

    return var5;
}
```

​     注意:  CAS是一种系统原语(硬件支持),整个过程是不允许被中断  

​        cas :缺点 :有可能自旋时间过长,对cpu造成了极大的负担

​        ABA : 其他线程修改了值,让另一个线程觉得没有被修改,从而完成了cas 操作,这就是ABA 问题

​    ABA:自学(类似版本号)

5 .Syn和Lock锁的区别和相同

​          1.   syn :是一把非公平锁

​                  lock :可以是公平锁 ,也可以是非公平锁  根据传入的参数决定到底是什么锁

​                  公平锁:按照申请锁的顺序来拿到锁,类似食堂排队

​                  非公平锁:后申请的人可能先拿到这把锁-> 在高并发情况下,可能导致 优先级反转和饥饿现象



​       2.syn和lock 都是可重入锁

​                        指的是:同一线程外层函数获得锁之后,内层递归函数仍能获得该锁的代码

​                        在同一线程在外层方法获得锁的时候,在进入内层方法会自动获得锁

​          可重入锁的意义:防止死锁

​               



​   

​   

​      



### 7.阻塞队列

1.阻塞队列好的一面

​      

2.不得不阻塞怎么管理

![1558100871299](C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\1558100871299.png)

在多线程领域:所谓阻塞,在某些情况下会被挂起(即阻塞),一旦条件满足,被挂起的线程又会自动被唤醒

为什么要使用阻塞队列:

好处是我们不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,这一切被都阻塞队列包办了,

在concurrent包发布以前,在多线程情况下,程序员都需要自己去控制这些细节,还要兼顾效率和安全,而阻塞队列的出现就给我们带来不小的复杂度



这里我们重点介绍3个阻塞队列

​          1.arrayBlockingQueue :由数组结构组成的有界阻塞队列

​      2.LinkedBolckingQueue:由链表结构组成的有界(大小默认值是 Integer.MAX_VALUE) 阻塞队列

​      3.SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列

阻塞队列的常见方法

![1558102296083](C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\1558102296083.png)



###

  



​           







​     

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马