JUC多线程及高并发2-----volatile

JMM-----可见性代码证明(面试题笔记2)

2.请谈谈JMM

  1. 可见性(VolatileDemo代码演示)
  2. 原子性(VolatileDemo代码演示)
  3. 有序性

2.1可见性(VolatileDemo代码演示)

对比

新建项目Java工程

package jMM;

import java.util.concurrent.TimeUnit;

//1.
public  class Jmm_kejianxing {
    int number =0;   //原主机的数据
    public  void  addT060(){
        this.number =60;   //之后数据改变为60
    }
}
/*
* 1.验证volatile的可见性
*  1.1 假如 int number =0 ;number变量之前根本没有添加volatile关键字修饰
* */
class   VolatileDemo{
    public static void main(String[] args) //main方法是一切方法的运行入口
    {
        Jmm_kejianxing jmm_kejianxing =new Jmm_kejianxing();//资源类

//俩个实现多线程方法---1.实现Runnable接口,2.继承Thread类
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//            }
//        }).start();
        new Thread(
                () -> {
           System.out.println(Thread.currentThread().getName()+"\t come in");
           //暂停一会儿线程
           try {TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e){e.printStackTrace();}
                    jmm_kejianxing.addT060();
            System.out.println(Thread.currentThread().getName()+"\t update number value"+jmm_kejianxing.number);

           },"AAA").start();
    //第二个线程就是我们的main线程
    while (jmm_kejianxing.number == 0){
        //main 线程就一直再这里等待循环,直到number值不再等于0
    }
        System.out.println(Thread.currentThread().getName()+"\t mission is over");
    }
    }

结果:

AAA	 come in
AAA	 update number value60

因为没有用volatile方法的可见性,所以结果并没有结束,一直执行
也就是说A线程已经把0改为60,再次输入主线程,但其他线程不知道。

正确的
package jMM;

import java.util.concurrent.TimeUnit;

//1.
public  class Jmm_kejianxing {
    volatile int number =0;   //原主机的数据
    public  void  addT060(){
        this.number =60;   //之后数据改变为60
    }
}
/*
* 1.验证volatile的可见性
*  1.1 假如 int number =0 ;number变量之前根本没有添加volatile关键字修饰
* */
class   VolatileDemo{
    public static void main(String[] args) //main方法是一切方法的运行入口
    {
        Jmm_kejianxing jmm_kejianxing =new Jmm_kejianxing();//资源类

//俩个实现多线程方法---1.实现Runnable接口,2.继承Thread类
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//            }
//        }).start();
        new Thread(
                () -> {
           System.out.println(Thread.currentThread().getName()+"\t come in");
           //暂停一会儿线程
           try {TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e){e.printStackTrace();}
                    jmm_kejianxing.addT060();
            System.out.println(Thread.currentThread().getName()+"\t update number value"+jmm_kejianxing.number);

           },"AAA").start();
    //第二个线程就是我们的main线程
    while (jmm_kejianxing.number == 0){
        //main 线程就一直再这里等待循环,直到number值不再等于0
    }
        System.out.println(Thread.currentThread().getName()+"\t mission is over");
    }
    }

结果:

AAA	 come in
AAA	 update number value60
main	 mission is over

Process finished with exit code 0

2.2不保证原子性(VolatileDemo代码演示)

package jMM;

import java.util.concurrent.TimeUnit;

//1.
public  class Jmm_kejianxing {
    volatile int number =0;   //原主机的数据
    public  void  addT060(){
        this.number =60;   //之后数据改变为60
    }
    public void addPlusPlus(){
        number++;
    }
}
class VolatileDemo1{
        public static void main(String[] args) {
            Jmm_kejianxing jmm_kejianxing = new Jmm_kejianxing();
            for (int i = 1; i < 20; i++) {
                new Thread(() -> {
                    for (int j = 1; j <= 1000; j++) {
                        jmm_kejianxing.addPlusPlus();
                    }
                }, String.valueOf(i)).start();
            }
            //需要等待上面20个线程都全部计算完成后,再用main线程取得最终结果值是多少?
//            //暂停 一会儿线程
////            try {
////                TimeUnit.SECONDS.sleep(5);
////            } catch (InterruptedException e) {
////                e.printStackTrace();
////            }
            while(Thread.activeCount()>2){
                Thread.yield();}
            System.out.println(Thread.currentThread().getName()+"\t finally number value:"+ jmm_kejianxing.number);
        }
//volatile可以保证可见性,及时通知其他线程,主物理内存的值已经被修改
        public static void seeokByVolatile()
        {
            Jmm_kejianxing jmm_kejianxing = new Jmm_kejianxing();//资源类

            new Thread(
                    () -> {
                        System.out.println(Thread.currentThread().getName() + "\t come in");
                        //暂停一会儿线程
                        try {
                            TimeUnit.SECONDS.sleep(3);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        jmm_kejianxing.addT060();
                        System.out.println(Thread.currentThread().getName() + "\t update number value" + jmm_kejianxing.number);

                    }, "AAA").start();
            //第二个线程就是我们的main线程
            while (jmm_kejianxing.number == 0) {
                //main 线程就一直再这里等待循环,直到number值不再等于0
            }
            System.out.println(Thread.currentThread().getName() + "\t mission is over");
        }
    }

结果:

main	 finally number value:18804

每刷新一次,结果都不一致。

你可能感兴趣的:(java,JUC,2019面试题)