0

What I understand by synchronizing static object which is a variable, if one thread is accessing it, other thread can't.

    class T3
    {
    static Integer i = 0;
    
    static void callStatic()
    {
        synchronized(T3.class)
        {
            System.out.println(i++);
            while(true);
        }
    }
    
    public void notStatic()
    {
        System.out.println(i++);
        while(true);
    }
    }

    class T2 implements Runnable
{
    public void run()
    {
        System.out.println("calling nonstatic");
        new T3().notStatic();
    }
}

class T implements Runnable
{
    public void run()
    {
        System.out.println("calling static");
        T3.callStatic();
    }
}

public class Test
{
    public static void main(String[] args)
    {
        new Thread(new T()).start();
        try
        {
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
        }
        new Thread(new T2()).start();
    }
}

But this demo program has output as :

calling static

0

calling nonstatic

1

Is my understanding wrong? Or am I missing something?

I tried, synchronzing callStatic method, and synchronizing T3.class class object too. But none worked as I thought.

Note : I thought, 1 will not be printed as callStatic has lock on variable i and is in infinite loop.

2
  • 2
    Pleas take the time to format your code with consistent indentation and such when asking for help. Commented May 1, 2014 at 9:22
  • 2
    Your edit changing synchronized(i) to synchronized(T3.class) markedly changes the question. Markedly changing the question such that it invalidates the answers is not cool. If you want to ask the question of what happens with synchronized(T3.class), that's fine, but do it separately. Your previous question has answers. Commented May 1, 2014 at 9:41

3 Answers 3

3

You don't synchronize on variables, you synchronize on objects.

callStatic synchronizes on 1 and then sets i to 2. If notStatic were to enter a synchronized(i) block at this point, it would synchronize on 2. No other thread has locked 2, so it proceeds.

(Actually, 1 and 2 aren't objects, but Integer.valueOf(1) and Integer.valueOf(2) return objects, and the compiler automatically inserts the Integer.valueOf calls to convert ints to Integers)

In your code, notStatic doesn't actually synchronize at all. It's true that only one thread can be in a synchronized block for a particular object at a particular time, but that has no effect on other threads that are not trying to enter a synchronized block.

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

Comments

1

Note: This answer relates to the original question, which had synchronized(i), not synchronized(T3.class), in callStatic. The edit really changes the question.


synchronize acts on the object, not the variable/member holding it. There are a couple of important things going on in your code.

  • synchronize(i) does indeed synchronize access to i provided that the other code trying to use it also synchronizes. It has no effect on code that doesn't synchronize. Suppose Thread A does synchronize(i) and holds it (your infinite loop); then Thread B does System.out.println(i); Thread B can happily read i, there's nothing stopping it. Thread B would have to do

    synchronize (i) {
        System.out.println(i);
    }
    

    ...in order to be affected by Thread A's synchronize(i). Your code is (attempting to) synchronized mutation, but not access.

  • i++; with an Integer is effectively equivalent to i = new Integer(i.intValue() + 1), because Integer is immutable. So it creates a different Integer object and stores that in the i member. So anything synchronizing on the old Integer object has no effect on code synchronizing on the new one. So even if your code were synchronizing both access and mutation, it wouldn't matter, because the synch would be on the old object.

    This means that the code in your callStatic is synchronizing on an instance of Integer and then repeated creating a bunch of other instances, which it is not synchronizing on.

6 Comments

what if I replace Integer by a mutable class?
@Batty: Then your callStatic would keep a lock on it (as long as you don't assign a new instance to i), and any code trying to synchronize on that same object would wait until the lock was released. Code not synchronizing on that object would not wait.
+1: Thanks for explaining that Integer i = 0; i++ actually creates a new object. I've made this mistake before as well.
your comment explains pretty much.
@Batty: Yeah, definitely. There are two major things at work here: Synchronizing on an object (not a variable or data member holding it), and the fact that it only happens when both sides do it. So code synchronizing on T3.class will cooperate with code synchronizing on T3.class but not code synchronizing on anything else. Code that doesn't synchronize, doesn't synchronize.
|
1

Synchronized blocks on static and non static don't block each other. You need to understand how synchronized works for this. Synchronized is done always on an object never on a variable. When you synchronize, thread takes a lock on the object's monitor, the object which you put in the synchronized statement braces.

Synchronized blocks on static references (like in your code) lock on the .class object of your class and not on any instance of that class. So static and non-static synchronized blocks don't block each other.

Now in your code the notStatic method doesn't synchronize on anything where as the callStatic synchronizes on the static i Integer object. So they don't block each other.

9 Comments

"Synchronized blocks on static and non static don't block each other." That's irrelevant here. The OP isn't using synchronized on methods, he/she is using it on a specific object. "Synchronized blocks on static references (like in ur code) lock on the .class object of your class" No, the OP's code is not synchronizing on the class, it's synchronizing on i.
thats very relevant here. Th OP mis-understand how synchronized blocks on statics work.
Nazgul: Look at the code again. The OP is synchronizing on a specific object. The distinction you're discussing relates to synchronized on methods, not in code where you give it a specific object to sync on.
ha ha. really true. Missed on may part. Thanks TJ.
Nazgul: (OT) Nice to talk with someone who actually listens rather than just reacting. Rare quality, nice one.
|

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.