K.JH
K.JH

Reputation: 21

Thread can't be called

class client
{
    static int data = 0;
    public static void main(String[] args)
    {
        new Thread(new Runnable() 
        {
            @Override
            public void run()
            {
                while(true)
                {
                    //System.out.print("");
                    if(data == 1) {System.out.println("GOTCHA");}
                }
            }
        }).start();
        Scanner sc = new Scanner(System.in);
        while(true)
        {
            data = sc.nextInt();
        }
    }
}

I don't understand why it doesn't work when I type 1. and there is a funny situation that if I remove comment(System.out.print("")), It works. I can make it another way like callback Method, only I want is why It doesn't work.

Upvotes: 0

Views: 61

Answers (1)

Stephen C
Stephen C

Reputation: 718826

The short version is that shared variables should EITHER be declared as volatile OR accesses / updates to the variables should be done using an appropriate synchronization mechanism. An appropriate synchronization mechanism could be:

  • Use of primitive monitors; i.e. synchronized blocks or methods with the same target object.

  • Use of a Lock.acquire and Lock.release on the same lock object.

  • Something else with appropriate happens before relationships. (Don't worry about this case. It is complicated. But if you want to, read up about the Java Memory Model.)

At any rate, if two threads share a (non-volatile) variable without appropriate synchronization, then one thread is not guaranteed1 to see the value written by the other thread. That is what was happening with your example. The child thread never sees the results of the parent thread's write.

This is normal behavior with multi-threading in Java. And one of the reasons why concurrent programming in Java is tricky.


1 - In some cases the data will be visible, and others it won't. It can depend on the Java version, the operating system, the hardware platform, whether you are debugging or not, and various other things. There are at least two possible causes of the visibility issues. 1) It is often due to memory caching issues; e.g. changes made by one thread not being flushed to main memory so that the other thread can see them. 2) Alternatively, it could (in theory at least) be due the JIT compiler optimizing away memory fetches. To understand exactly what is going on, you would need to analyze the native code emitted by the JIT compiler. But either way, these behaviors are permitted by the Java Memory Model ... if the required happens before relationships do not exist.

Upvotes: 1

Related Questions