Java – why is an object sometimes null when it is initialized in a thread and accessed from main?

When I create a new object in a thread, it is a property of an object. I give the thread that it remains null in the main function (but there is no system. Out) I wrote a simple problem example with the same results:

public class T1 {
    public T2 t2;
}
public class T2 {
    public String s;
    /**
     * @param args
     */
    public static void main(String[] args) {
        T1 t1 = new T1();

        T3 thread = new T3(t1);
        thread.start();

        while(t1.t2 == null){
    //      System.out.println("null");
        }
        System.exit(0);
    }
}

public class T3 extends Thread{
    public T1 t1;

    public T3(T1 t1){
        this.t1 = t1;
    }

    @Override
    public void run(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t1.t2 = new T2();
        while(true){
            System.out.println(t1.t2);
        }
    }
}

Therefore, if there is no system out. Println ("null"), which causes an infinite loop, but when I add this system When out, it behaves as I suspect If I use static variables, I will even get the same result or problem

Is there some kind of optimization or something else I don't understand? Or why there is no system out. println(“null”)t1. T2 always = = null? I think the T1 object and its attributes (in this case, object T2) will be created on the heap. It is shared among all threads, and only T1 reference variable is stored in the stack So I hope someone can explain to me why it doesn't have a system Keep null in the case of out... If the thread executes after the while loop, there will be a problem, which is why there is a sleep (1000)

Solution

If one thread is updating a value that another thread is reading, there must be some kind of memory synchronization Add system out. When println (...), it uses the underlying printstream as the synchronization class Therefore, the call to println (...) synchronizes memory between threads

This is some good news about memory synchronization from Oracle

You should add volatile to T2 T2; Field to display the update of T2 between threads

The real problem here is that with modern multi CPU (and core) hardware, each CPU has its own cache memory Modern operating systems and JVM software use these physical (and virtual) CPUs to arrange threads to run in parallel at the same time These caches are a critical part of thread performance If you have to enter the central memory for every read and write, your application will run twice as slow The memory synchronously flushes the cache so that local writes can be written to the central storage. Local cache reads are marked as dirty, so they must be re read from the central storage if necessary

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>