Kasun
Kasun

Reputation: 561

Class Level and Object Level lock synchronization

class MyClass
{
    public synchronized void print() {}

    public static synchronized void buffer() {}
}

Making static object synchronized makes a CLASS level object where only one Thread can access this. The class has both static and non-static Synchronized methods.

  1. Can other threads(Thread-B) access non-static synchronize methods() via object lock while another Thread (Thread-A) using static synchronized (Acquiring a class level lock) method?

  2. I hope non of the threads access any of the static synchronized methods until (Thread-B) release the lock.

Upvotes: 1

Views: 5286

Answers (3)

Mohammed Imran
Mohammed Imran

Reputation: 51

static locks
synchronized(YourClass.class/class object)

instance locks
synchronized(this/instance object)
both are not mutually exclusive, both thread will run concurrently

Upvotes: 0

morgano
morgano

Reputation: 17422

In short:

  • non-static methods use the current object's lock (only one thread per object)

  • static methods use the associated Class object (there is one per class, so, only one therad per Class object)

It's important to take into account erasure:

// If you have this:

class MyClass<T> {

    static synchronized myMethod() { ... }

}

MyClass<Integer> objInt = new MyClass<Integer>();

MyClass<String> objString = new MyClass<String>();

// Then only one thread will be able to execute myMethod(),
// even when ojbInt and ObjString are not "exactly" the "same"
// class in compilation time

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727137

The answers to both your questions are "yes": static-level locks do not block instance-level synchronized methods, and they apply to all static synchronized methods.

Generally, though, synchronizing on the class is discouraged, because it leaves your class exposed to an infinite wait attack. The perpetrator synchronizes on the class, preventing all your static synchronized methods from running. A better approach is to make a private object for locking, and synchronize on it, like this:

class MyClass
{
    public synchronized void print() {}

    private static Object staticLock = new Object();
    public static void buffer() {
        synchronized(staticLock) {
            ...
        }
    }
}

Same goes for synchronizing the instance methods: if the class is to be used in potentially non-cooperative environment, you are better off with a private object for locking.

Upvotes: 4

Related Questions