Java中的static变量难道不能保证volatile的可见性吗?

 //在没有同步的情况下共享数据
public class NoVisibility {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while (!ready)
               Thread.yield();
            System.out.println(number);
        }
    }

    public static void main(String[] args) {
        new ReaderThread().start();
        number = 42;
        ready = true;
   }
}

引发的问题有

NoVisibility 可能会持续循环下去,因为ReaderThread可能永远看不到ready写入的值
NoVisibility 可能会输出0,因为ReaderThread可能看到了ready写入的值,但是没有看到写入的number的值(这种现象叫重排序)


但是在我们使用static变量的时候,比如HashMap作为static变量的时候,我们根本没有担心过可见性的问题啊,修改后的HashMap我们总是认为是可见的对其他线程

static只是表示这个变量是该类所有实例共享的。volatile是表示变量在使用时直接去共享内存中获取,而不是从当前线程的私有内存区域存取。通常在线程开启时,会将使用到的变量产生一个线程内的副本,与主线程内存中的数据不同步。

但是在我们使用static变量的时候,比如HashMap作为static变量的时候,我们根本没有担心过可见性的问题啊,修改后的HashMap我们总是认为是可见的对其他线程

static保证该变量是静态的,也就是没有副本,volatile是保证多个线程同时修改后,始终能反映最新修改结果的,2个概念不一样

volatile 能保证读取和修改是同一个值
static 只能保证修改的是同一个内存地址上的值

不行,除非对这个变量加锁或添加volatile修饰,否则一个线程对其修改可能不会立马同步到主存中,因此其他线程不会立马可见。加锁或volatile在每次对一个字段写入会强制刷新到主存

static保证的是当类被正确构造的时候它的初始化引用对所有 线程可见,并不是说当引用改变之后依然保持对其他线程的可见性

并不能保证内存可见性,我已经测试过了,static变量在方法区,一样会被线程共享,会在本地内存留一个副本,需要用volitile进行同步才可以的