0

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();
    }
}    
7
  • 1
    this code is not thread safe! Commented Aug 14, 2013 at 7:09
  • that is what i meant. Commented Aug 14, 2013 at 7:12
  • 2
    Terrible code. Please don't begin your Java learning looking at rubbish like this. (No synchronisation, errant sleep calls etc). Read this instead: docs.oracle.com/javase/tutorial/essential/concurrency Commented Aug 14, 2013 at 7:12
  • @bennihepp: no shared state? What about the counter? And the object? They're both static. Commented Aug 14, 2013 at 7:13
  • 2
    Why create new object o again inside run()? Commented Aug 14, 2013 at 7:14

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

It is worth mentioning explicitly that ++ is a read and write operation. It is thus not atomic.
1

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.

2 Comments

Really you ought to say static final Object o = new Object(); to prevent programmers reassigning o thereby introducing bugs cased by synchronising on different objects.
I didn't get what you are trying to say. Sorry about that.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.