简体   繁体   中英

Java multi-thread

I'm a novice java programmer and kind of confused by the following code snippet. Does it mean the first thread coming in will share the lock with the third one? Hope someone could help me clarify. Thanks in advance.

public class T_6 extends Thread    {
    static Object o = new Object();
    static int    counter = 0;
    int id;

    public T_6(int id)  {
        this.id = id;
    }

    public void run () {
        if ( counter++ == 1 )    //confused in here.                
            o = new Object();

        synchronized ( o ) { 
            System.err.println( id + " --->" );
            try {
                sleep(1000);
            } catch (  InterruptedException e ) {
                System.err.println("Interrupted!");
            }
            System.err.println( id + " <---" );
        }
    }

    public static void main (String args []) {
        new T_6(1).start();
        new T_6(2).start();
        new T_6(3).start();
    }
}    

When you reach the up-count and if, you do a typical check-then-act operation. The problem here is that several threads can come here at the same time. This will mean they will have local copies of the counter . The different threads may all have a 0 local copy - meaning they will count up to 1 and create new objects - all of them. But they are stored in a static container - of which they may or may not have local copies. In short, whatever happens here is accidental. They may end up synchronizing over the same object - but they may try to synchronize over different objects, meaning they won't synchronize at all.

You should have a look at the final and volatile keywords.

final means a reference can't be repointed once pointed somewhere. This is a good idea for locks. If you change your declaration to

final static Object o = new Object();

you are guaranteed that o cannot change, and all synchronizations will be over the same object.

volatile means it is forbidden for the VM to store a thread-local copy of a variable. All reads and writes must be to memory. This means that all threads will see writes that other threads do.

To ensure proper synchronization between multiple threads, all must acquire lock on the same object , or else synchronization will not be achieved.

Take a look at this part of your code:

 if ( counter++ == 1 )    //confused in here.                
        o = new Object();

This part is not necessary at all to make the code thread-safe. Remove the above code which is causing confusion. You have already created instance of the object while declaring it. Now to ensure thread-safety between all the threads, make them acquire lock on the same object which you have already created.

Look here : static final Object o = new Object();

Just make the object final, to ensure you do not assign new value anywhere else in the code mistakenly/intentionally. You can directly use this object in synchronized fashion to ensure thread safety.

Does it mean the first thread coming in will share the lock with the third one?

Yes, moreover, due to:

  1. non-volatile static int counter = 0 variable
  2. non-atomic operation ++

each thread will have its own copy of variable counter . It means that the following condition never true :

if ( counter++ == 1 )    
   o = new Object();

That's why all of these threads will share the same lock on object o initialized when declaring o .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM