1. volatile是java虚拟机提供的轻量级的同步机制

  • 保证可见性
  • 不保证原子性
  • 禁止指令重排

    2. JMM(java内存模型)你谈谈?

    JMM(Java内存模型)本身是一种抽象的概念并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。
    JMM关于同步的规定:
  1. 线程解锁前,必须把共享变量的值刷新回主内存。
  2. 线程加锁前,必须读取内存的最新值到自己的工作内存。
  3. 加锁解锁必须是同一把锁。

image.png

2.1 可见性

某个线程修改了值并写入了主物理内存后,要及时通知其他线程。
volatile - 图2

2.2 原子性

不可分割,完整性,也即某个线程正在做某个具体业务时,中间不可以被加塞或者被分割。 需要整体完整,要么同时成功,要么同时失败。
如何解决原子性?

  • 加synchronized
  • 使用JUC下的AtomicInteger (num++)

    2.3 volatile代码演示可见性

    ```java public class VolatileDemo { public static void main(String[] args) {

    1. volatileVisibilityDemo();
    2. atomicDemo();

    }

    private static void atomicDemo() {

    1. System.out.println("原子性测试");
    2. MyData myData=new MyData();
    3. for (int i = 1; i <= 20; i++) {
    4. new Thread(()->{
    5. for (int j = 0; j <1000 ; j++) {
    6. myData.addPlusPlus();
    7. myData.addAtomic();
    8. }
    9. },String.valueOf(i)).start();
    10. }
    11. while (Thread.activeCount()>2){
    12. Thread.yield();
    13. }
    14. System.out.println(Thread.currentThread().getName()+"\t int type finally number value: "+myData.number);
    15. System.out.println(Thread.currentThread().getName()+"\t AtomicInteger type finally number value: "+myData.atomicInteger);

    }

    //volatile可以保证可见性,及时通知其它线程主物理内存的值已被修改 private static void volatileVisibilityDemo() {

    1. System.out.println("可见性测试");
    2. MyData myData=new MyData();//资源类
    3. //启动一个线程操作共享数据
    4. new Thread(()->{
    5. System.out.println(Thread.currentThread().getName()+"\t come in");
    6. try {
    7. TimeUnit.SECONDS.sleep(3);
    8. myData.setTo60();
    9. System.out.println(Thread.currentThread().getName()+"\t update number value: "+myData.number);
    10. }catch (InterruptedException e)
    11. {
    12. e.printStackTrace();
    13. }
    14. },"AAA").start();
    15. while (myData.number==0){
    16. //main线程持有共享数据的拷贝,一直为0
    17. }
    18. System.out.println(Thread.currentThread().getName()+"\t mission is over. main get number value: "+myData.number);

    } }

class MyData{ int number=0; //volatile int number=0;

  1. AtomicInteger atomicInteger=new AtomicInteger();
  2. public void setTo60(){
  3. this.number=60;
  4. }
  5. //此时number前面已经加了volatile,但是不保证原子性
  6. public void addPlusPlus(){
  7. number++;
  8. }
  9. public void addAtomic(){
  10. atomicInteger.getAndIncrement();
  11. }

} ```

2.4 有序性(了解)

volatile - 图3
重排案例1
volatile - 图4
重排案例2
volatile - 图5
禁止指令重排小总结(了解)
volatile - 图6
volatile - 图7

3. 你在哪些地方使用过volatile?

单例模式DCL代码
image.png