Java synchronized static methods: lock on object or class
Asked Answered
T

8

150

The Java documentation says:

it is not possible for two invocations of synchronized methods on the same object to interleave.

What does this mean for a static method? Since a static method has no associated object, will the synchronized keyword lock on the class, instead of the object?

Twobit answered 13/1, 2009 at 0:48 Comment(0)
A
131

Since a static method has no associated object, will the synchronized keyword lock on the class, instead of the object?

Yes. :)

Ashcraft answered 13/1, 2009 at 0:53 Comment(9)
Please answer Elaborate so that everyone can understand.Cupola
@Madhu. It means that if you have 2 or more synchronized methods on the same class, both cannot execute at the same time, even when there are multiple instances of that class. The locking is essentially the same as locking on the Object.class for each synchronized method.Stgermain
This answer is wrong -this is the lock acquired on instance methods-, please fix it Oscar.Asterism
@vemv The question is regarding class methods, not instance methods.Ashcraft
Note that you don't include this context in your question - and neither it is on the question's title.Asterism
@vemv Well yes, to understand the answer you have to read the question first.Ashcraft
Which is better ?Making the static methods synchronized or using a synchronized block with a static object lock inside such methods, or are they same?Measure
what if the class object is an abstract class @AshcraftExpansion
@Expansion The class itself. When you inherit from that class now the child class is the class. gist.github.com/oscarryz/263171aff2064c3162ebfb79faaf499cAshcraft
G
203

Just to add a little detail to Oscar's (pleasingly succinct!) answer, the relevant section on the Java Language Specification is 8.4.3.6, 'synchronized Methods':

A synchronized method acquires a monitor (§17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.

Graphics answered 13/1, 2009 at 2:58 Comment(1)
Useful, I was looking for that quote +1Ashcraft
A
131

Since a static method has no associated object, will the synchronized keyword lock on the class, instead of the object?

Yes. :)

Ashcraft answered 13/1, 2009 at 0:53 Comment(9)
Please answer Elaborate so that everyone can understand.Cupola
@Madhu. It means that if you have 2 or more synchronized methods on the same class, both cannot execute at the same time, even when there are multiple instances of that class. The locking is essentially the same as locking on the Object.class for each synchronized method.Stgermain
This answer is wrong -this is the lock acquired on instance methods-, please fix it Oscar.Asterism
@vemv The question is regarding class methods, not instance methods.Ashcraft
Note that you don't include this context in your question - and neither it is on the question's title.Asterism
@vemv Well yes, to understand the answer you have to read the question first.Ashcraft
Which is better ?Making the static methods synchronized or using a synchronized block with a static object lock inside such methods, or are they same?Measure
what if the class object is an abstract class @AshcraftExpansion
@Expansion The class itself. When you inherit from that class now the child class is the class. gist.github.com/oscarryz/263171aff2064c3162ebfb79faaf499cAshcraft
L
81

One point you have to be careful about (several programmers generally fall in that trap) is that there is no link between synchronized static methods and sync'ed non static methods, ie:

class A {
    static synchronized f() {...}
    synchronized g() {...}
}

Main:

A a = new A();

Thread 1:

A.f();

Thread 2:

a.g();

f() and g() are not synchronized with each other and thus can execute totally concurrently.

Liatrice answered 13/1, 2009 at 11:2 Comment(3)
but what if g() is mutating some static variable which f() is reading. How do we make that thread safe? Do we explicitly acquire a lock on the class then?Cult
Yes, your non-static method must explicitly synchronize on the class itself (ie, synchronized (MyClass.class) {...}.Liatrice
@Liatrice "synchronized (MyClass.class) {...}" is equivalent to make this method static synchronized, right?Reredos
S
15

Unless you implement g() as follows:

g() {
    synchronized(getClass()) {
        ...
    }
}

I find this pattern useful also when I want to implement mutual exclusion between different instances of the object (which is needed when accesing an external resource, for example).

Selenodont answered 5/2, 2010 at 21:19 Comment(1)
Note that there may actually be a chance of some very subtle and nasty bugs here. Remember getClass() returns the runtime type; if you subclass the class, then the parent class and the child class will synchronize on different locks. synchronized(MyClass.class) is the way to go if you need to ensure all instances use the same lock.Graphics
S
3

Have a look at oracle documentation page on Intrinsic Locks and Synchronization

You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

Sunset answered 1/11, 2016 at 8:6 Comment(0)
I
2

A static method also has an associated object. It belongs to Class.class file in JDK toolkit. When the .class file load into the ram, the Class.class creates a instance of it called template object.

Eg :- when you try to create object from existing customer class like

Customer c = new Customer();

The Customer.class load into RAM. In that moment Class.class in JDK toolkit creates an Object called Template object and load that Customer.class into that template object.Static members of that Customer.class become attributes and methods in that template object.

So a static method or attribute also has an object

Institutive answered 9/11, 2016 at 4:55 Comment(0)
H
2

Below examples gives more clarity between class and object lock, hope below example will help others as well :)

For example we have below methods one acquire class and other acquire object lock :

public class MultiThread {

    public static synchronized void staticLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

    public synchronized void objLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

So, now we can have following scenarios :

  1. When threads using same Object tries to access objLock OR staticLock method same time (i.e. both threads are trying to access same method)

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  2. When threads using same Object tries to access staticLock and objLock methods same time (tries accessing different methods)

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
  3. When threads using different Object tries to access staticLock method

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  4. When threads using different Object tries to access objLock method

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
Hazlett answered 13/8, 2017 at 4:45 Comment(0)
P
0

For those who are not familiar static synchronized method locked on class object e.g. for string class, it's String.class while instance synchronized method locks on the current instance of Object denoted by “this” keyword in Java.

Since both of these objects are different they have a different lock so while one thread is executing the static synchronized method, the other thread in java doesn’t need to wait for that thread to return instead it will acquire a separate lock denoted byte .class literal and enter into the static synchronized method.

Source: https://javarevisited.blogspot.com/2012/03/mixing-static-and-non-static.html

Philter answered 24/5, 2017 at 2:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.