简体   繁体   中英

Java - Synchronized block works differently than method

I am trying to figure out, what the difference between a synchronized block and a synchronized function actually is. This Code works perfectly, as it avoids mistakes in the critical section

class ThreadSynchronous extends Thread {
static int m_count = 0;
String s;

ThreadSynchronous(String s) {
    this.s = s;
}

public void run() {
    synchronized (getClass()) {
        ...
    }
}
}

public class ThreadExample {
public static void main(String[] args) {
    Thread t1 = new ThreadSynchronous("Thread1: ");
    Thread t2 = new ThreadSynchronous("Thread2: ");
    t1.start();
    t2.start();

    try{
        t1.join();
        t2.join();
    } catch (InterruptedException e){
    }
}
}

But if I use public synchronized void run() instead, it doesn't work equally/properly.

Per the JLS 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.

In the synchronized (getClass()) block you synchronize on the Class object, thus all instances of ThreadSynchronous are serialized.

When you make the instance method synchronized , you are synchronizing only on that instance (the this reference).

The two synchronize on different objects.

synchronized (getClass()) { ... } synchronizes on the class, so of your two Thread instances, only one at a time can enter the block.

On the other hand, public synchronized void run() { ... } synchronizes on the instance, so both of the two instances can enter the block in parallel. Only if a single instance were shared by multiple threads, then this block would allow only one of them to execute.

Synchronized methods synchronize on the instance for normal instance methods, and on the class object for static methods.

So, if your run() method could be refactored to become a static one, then the synchronized method keyword would give you the synchronized (getClass()) { ... } behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM