咦,咋没加volatile,变量也可见的呢?

本想今天覆习一下volatile的,结果在写demo时,怎么也达不到效果。还以为写错的呢。最后发现是 System.out.printlnr惹的祸。

我的demo如下:
定义一个变量控制线程的中断。
最初的demo是这样的:

class Test1{
	//public volatile static  int num =0; 
    public static  int num =0;
    public static void main(String[] args) {
        new Thread(()->{
            while (num==0){
                System.out.println(Thread.currentThread().getName());

            }
        },"thredname --1").start();


        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        num = 1;
        System.out.println(num);

    }
}

不成功后,又换成多线程


class Test1{
     //    public static  int num =0;
    public static void main(String[] args) {
        test11 test11 = new test11();
        
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                while (test11.num==0){
                    System.out.println(Thread.currentThread().getName());

                }
            },"thredname --"+i).start();
        }


        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        test11.num = 1;
        System.out.println(test11.num);

    }
}

class test11{
    public   int num =0;
}

妈耶,还是不行,啥情况?
于是百度volatile,也是这样的呢,还找视频了,也是这样啊?
突然弹幕说为啥多了一个sout就不行了?
我靠,惊醒梦中人。
注释掉果然是自己想要的结果了。

不过是为啥呢?又百度了(这个习惯有点不好,没有自己的思考就直接查原因,要改正
原来这个pringtIn竟然是线程安全的
源码如下:

public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

咦,为啥加锁会是变量可见呢。这个在一个博客中是这么说的:
加锁的含义不仅仅局限于互斥行为,还包括内存可见性

  • JMM关于Synchronized的两条规定:

    • 线程解锁前,必须把共享变量的最新值刷新到主内存中;
    • 线程加锁时,讲清空工作内存中共享变量的值,从而使用共享变量是需要从主内存中重新读取最新的值(加锁与解锁需要统一把锁)
  • 线程执行互斥锁代码的过程:

    • 获得互斥锁
    • 清空工作内存
    • 从主内存拷贝最新变量副本到工作内存
    • 执行代码块
    • 将更改后的共享变量的值刷新到主内存中
    • 释放互斥锁

ok ,找到原因。

总结:还是基础弱,还是要多看书,多练习。

附录:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章