java中用volatile修饰的静态变量线程可见,不修饰我发现还是可见,不知道怎么回事????

下图:

图片说明

我没有用volatile修饰,在线程中起一个新的线程,在主线程睡眠15秒后,将run改为false,另一个线程就停了,这是不是说明run是线程可见的

图片说明

到底是哪里错了...

因为你的线程里用到log.debug打印了信息,而打印处理的底层代码用到同步锁,所以线程会刷新本地的变量副本
你把while(run)循环的log.debug注释掉再执行试试看

可见性是指, 任意线程对一个变量进行了修改 , 其他变量读到的都是最新的值 .
CPU为了提高效率会把主内存中的值写到线程独享的工作内存中 , 但跟主内存做同步的时间间隙导致了线程可能无法读到最新的值 , volatile 可以保证每次都去主内存读取 ,所以保证了可见性.
static 表示这个变量在所有该类的实例中只有一份 , 但还是避免不了从主内存拷贝到工作内存 , 所以无法保证可见性 .
你运行看看下面这个实验 , 加不加volatile , 结果是不一样的
// private static volatile int MY_INT = 0;
private static int MY_INT = 0;

public static void main(String[] args) {
    new ChangeListener().start();
    new ChangeMaker().start();
}

static class ChangeListener extends Thread {
    @Override
    public void run() {
        int local_value = MY_INT;
        while (local_value < 5){
            if(local_value != MY_INT){
                System.out.println("Got Change for MY_INT: " + MY_INT);
                local_value = MY_INT;
            }
        }
    }
}

static class ChangeMaker extends Thread{
    @Override
    public void run() {
        int local_value = MY_INT;
        while (MY_INT < 5){
            System.out.println("Increment MY_INT to " + (local_value+1));
            MY_INT = ++local_value;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) { e.printStackTrace(); }
        }
    }
}
// 不加 volatile
Incrementing MY_INT to 1
Incrementing MY_INT to 2
Incrementing MY_INT to 3
Incrementing MY_INT to 4
Incrementing MY_INT to 5

// 加了volatile
Increment MY_INT to 1
Got Change for MY_INT: 1
Increment MY_INT to 2
Got Change for MY_INT: 2
Increment MY_INT to 3
Got Change for MY_INT: 3
Increment MY_INT to 4
Got Change for MY_INT: 4
Increment MY_INT to 5
Got Change for MY_INT: 5

你的这个程序似乎是没有被可见性的问题影响到 , 所以你会有static是不是保证了可见性的疑惑  , 但是单从你的程序来说 , 不足以证明static保证了可见性

https://blog.csdn.net/weixin_42008012/article/details/104673153