Can volatile decorate objects and arrays to ensure the visibility of their internal elements?

topic description

when volatile decorates objects and arrays, it only ensures the visibility of their reference addresses, but why does the following code print "over" immediately after I add volatile? if you don"t add volatile to the array, it will never print. What are the detailed steps for a thread to manipulate its fields or elements when volatile modifies objects and arrays? Ask the Great God for advice

related codes

/ / Please paste the code text below (do not replace the code with pictures)
public class b {

public static volatile int[] ints = new int[5];
public static void main(String[] args) throws Exception {
    Object o = new Object();
    new Thread(() -> {
        //A
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       ints[0] = 2;
    }).start();
    new Thread(() -> {            //B
        while (true) {
            if (ints[0] == 2) {
                System.out.println("");
                break;
            }
        }
    }).start();
}

}

Feb.22,2022

I asked the subject's question on stackoverflow , question link , and someone also gave a more reliable answer:

.

clipboard.png

Java:3.1.4

clipboard.png

ThreadAints[0]intsvolatile,intsints[0]


volatileJavaConcurrentHashMap1.8volatiletableDoug LeaUnsafegetObjectVolatilevolatile


:
clipboard.png

first of all, if you don't add volatile to the array, you will never print . Even without adding volatile,cpu, you will flush the value of int [0] from thread cache to main memory when you are free, but while (true) is too fast, causing cpu to be busy all the time. You can try to see what happens after adding a line of code:

public static int[] ints = new int[5];
public static void main(String[] args) throws Exception {
    Object o = new Object();
 new Thread(() -> {
        //A
 try {
            TimeUnit.MILLISECONDS.sleep(100);
 } catch (InterruptedException e) {
            e.printStackTrace();
 }
        ints[0] = 2;
 }).start();
 new Thread(() -> {            //B
 while (true) {
            try {
                Thread.sleep(0L);
 } catch (InterruptedException e) {
                e.printStackTrace();
 }
            if (ints[0] == 2) {
                System.out.println("");
 break; }
        }
    }).start();
}

A slight change will end normally

Menu