当前位置: 动力学知识库 > 问答 > 编程问答 >

multithreading - static members when used in synchronized method or block in java

问题描述:

when i use a synchronized method over instance method the monitor is associated with 'this' and on the other hand when i have synchronized on my class (static) method the monitor is associated with class object what in case if i have a static variable used in non static method? will that be synchronized?

say

public class A{

public static int reg_no = 100;

public synchronized void registration(){

A.reg_no = some operation...

}

}

in the above case what will happen to the static variable reg_no if two or more threads compete for the method registration()

网友答案:

When annotating a member function with synchronized, the method is synchronized on the instance of the object. If you want to synchronize on a static variable, you must manually synchronize on the class object:

public synchronized void registration() {
    synchronized (A.class) {
        A.reg_no = some operation ...
    }
}

Note that the above obtains two locks, which can lead to deadlocks if any other code obtains the same two locks in the other order. You may wish to remove synchronized from the method, leaving only synchronized (A.class).

网友答案:

Access to variables (static or instance) is not synchronized. The method's synchronization will guard against race conditions for a single instance, regardless of the variable (static or instance)

If you want to guard from multiple instances, you'd have to synchronize on the class literal, but this really looks wrong.

网友答案:

(Revised after some further thought)

For the example presented above you can get away with declaring your static int as volatile as punkers suggested.

In the general-case however - for example if your static variable were an object with mutable state ...

The synchronized instance method means that only the thread holding the object-instance lock is allowed to progress in that method of that instance of class A, and that when the thread finishes in the method and releases the lock any other thread entering any synchronized block using the same lock will "see" the changes you made.

It does not prevent changes being made to the static variable by another thread which:

  • assigns a new value to the static variable directly from outside class A (the variable is public!)
  • calls a static method of class A (synchronized or otherwise) which reassigns the static variable, because it will use a different lock
  • calls a non-synchronized instance method of class A

Using synchronized methods is generally a bit dangerous - they can lead to deadlocks because the lock can be taken externally by other code which uses your class/instance as the target of a synchronized block:

synchronized (objectOfTypeA) { ... } // takes the instance lock

or

synchronized (A.getClass()) { ... } // takes the class lock

A better approach might be to make the static variable private, add a private local variable to use as a lock (so it cannot be locked externally), and use the private local lock in synchronized blocks in your methods:

public class A {

    private static int reg_no = 100;
    private static Object lock = new Object();

    public void registration(){
        synchronized(lock) {
            reg_no = some operation...
        }
    }

    public static int getRegNo() {
        synchronized(lock) {
            return reg_no;
        }
    }
}
网友答案:

No, you need to synchronize the method to the class, eg. synchronized(A.class).

网友答案:

instead of add another syncronized block inside the syncronized method I would declare the static variable as volatile, if your problem is to share that variable with other threads.

分享给朋友:
您可能感兴趣的文章:
随机阅读: