Java synchronized static methods: lock on object or class
Since a static method has no associated object, will the synchronized keyword lock on the class, instead of the object?
Yes. :)
Static versus non-static lock object in synchronized block
The difference is simple: if the locked-on object is in a static
field, then all instances of MyClass*
will share that lock (i.e. no two objects will be able to lock on that object at the same time).
If the field is non-static, then each instance will have its own lock, so only calls of the method on the same object will lock each other.
When you use a static lock object:
- thread 1 calls
o1.foo()
- thread 2 calls
o1.foo()
, will have to wait for thread 1 to finish - thread 3 calls
o2.foo()
, will also have to wait for thread 1 (and probably 2) to finish
When you use a non-static lock object:
- thread 1 calls
o1.foo()
- thread 2 calls
o1.foo()
, will have to wait for thread 1 to finish - thread 3 calls
o2.foo()
, it can just continue, not minding thread 1 and 2
Which one of those you'll need depends on what kind of data you try to protect with your synchronized block.
As a rule of thumb, you want the lock-object to have the same static
-ness than the operated-on value. So if you manipulate non-static values only, you'll want a non-static lock object. If you manipulate static values only, you'll want a static lock object.
When you manipulate static and non-static values, then it'll become complicated. The easy way would be to just use a static lock object, but that might increase the size of the synchronized-block more than absolutely necessary and might need to more lock contention than desired. In those cases you might need a combination of static and non-static lock objects.
In your particular case you use the lock in the constructor, which will only ever be executed once per instance, so a non-static lock-object doesn't make any sense here.
Does the lock on a static synchronized method affect the non-static synchronized methods of it's instances?
A static synchronized
method will acquire the lock on the Class
instance for the class. A synchronized
method will acquire the lock on this
. When you acquire the class level lock by calling a synchronized static method, the object-level locks are not affected.
syncronized block inside static method will acquire Class level lock or Object level lock
Every object has a "monitor". When you use a synchronized block you specify the instance whose monitor you want to synchronize on. In addition to synchronized blocks there are also synchronized methods. A synchronized instance method will acquire the monitor of the instance the method was invoked on, whereas a synchronized static method will acquire the monitor of the java.lang.Class
object of the enclosing class.
public class Foo {
private static final Object STATIC_LOCK = new Object();
private final Object instanceLock = new Object();
public static void bar() {
synchronized (STATIC_LOCK) { // acquires monitor of "STATIC_LOCK" instance
// guarded code
}
}
public static synchronized void baz() { // acquires monitor of "Foo.class" instance
// guarded code
}
public void qux() {
synchronized (instanceLock) { // acquires monitor of "instanceLock" instance
// guarded code
}
}
public synchronized void quux() { // acquires monitor of "this" instance
// guarded code
}
}
If I make class level lock on static method & if one thread execute it so will it block other thread executing other instance method of same class?
the second thread will not be blocked。the class level lock & this class Object level lock,the two locks are different, but they can be re-entered each other
What is the use of static synchronized method in java?
In general, synchronized
methods are used to protect access to resources that are accessed concurrently. When a resource that is being accessed concurrently belongs to each instance of your class, you use a synchronized
instance method; when the resource belongs to all instances (i.e. when it is in a static
variable) then you use a synchronized static
method to access it.
For example, you could make a static
factory method that keeps a "registry" of all objects that it has produced. A natural place for such registry would be a static
collection. If your factory is used from multiple threads, you need to make the factory method synchronized
(or have a synchronized
block inside the method) to protect access to the shared static
collection.
Note that using synchronized
without a specific lock object is generally not the safest choice when you are building a library to be used in code written by others. This is because malicious code could synchronize on your object or a class to block your own methods from executing. To protect your code against this, create a private "lock" object, instance or static, and synchronize on that object instead.
Java - synchronizing static methods
Here's my test code that shows that you're right and the article is a bit over-cautious:
class Y {
static synchronized void staticSleep() {
System.out.println("Start static sleep");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("End static sleep");
}
synchronized void instanceSleep() {
System.out.println("Start instance sleep");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
System.out.println("End instance sleep");
}
}
public class X {
public static void main(String[] args) {
for (int i = 0; i < 2; ++i) {
new Thread(new Runnable() {
public void run() {
Y.staticSleep();
}
}).start();
}
for (int i = 0; i < 10; ++i) {
new Thread(new Runnable() {
public void run() {
new Y().instanceSleep();
}
}).start();
}
}
}
Prints:
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start static sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End static sleep
Start static sleep
End static sleep
So the static synchronized
has no bearing on the synchronized
methods on the instances...
Of course if static synchronised
methods are used throughout the system, then you can expect them to have the most impact on the throughput of a multithreaded systems, so use them at your peril...
Can we have multiple static locks in a class in java
First, this is sufficient:
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
Then, with your implementation, method1
and method2
are independent of each other, but only one instance of method1
or method2
can run among all instances of A
. If you want to allow different concurrent instances of A
so that method1
and method2
of different instances can run concurrently, just declare the locks without static
.
In other words: if a1
and a2
are instances of A
:
- with
static
locks, ifa1.method1
is running,a2.method1
cannot be run by another thread - without static,
a1.method1
can be run by only one thread.a1.method1
anda2.method1
can run concurrently.
Related Topics
Java Ee 6 @Javax.Annotation.Managedbean VS. @Javax.Inject.Named VS. @Javax.Faces.Managedbean
Java: Notify() VS. Notifyall() All Over Again
Using "Like" Wildcard in Prepared Statement
How to Compare Two Dates Without the Time Portion
Concurrentmodificationexception Despite Using Synchronized
Does Assigning Objects to Null in Java Impact Garbage Collection
Initial Size for the Arraylist
Is There an Executorservice That Uses the Current Thread
Exception Thrown in Catch and Finally Clause
What Is More Efficient, I++ or ++I
Similarity String Comparison in Java
How Is the Java Memory Pool Divided
How to Get the SQL of a Preparedstatement
How to Restart a Java Application
Swingpropertychangesupport to Dynamically Update Jtextarea
Get Query from Java.Sql.Preparedstatement
Difference Between Paint, Paintcomponent and Paintcomponents in Swing