Java同步块的工作方式与方法不同

Java同步块的工作方式与方法不同,java,critical-section,Java,Critical Section,我想弄清楚,同步块和同步函数之间的区别是什么。这段代码工作得很好,因为它避免了关键部分的错误 class ThreadSynchronous extends Thread { static int m_count = 0; String s; ThreadSynchronous(String s) { this.s = s; } public void run() { synchronized (getClass()) { ... } } } pub

我想弄清楚,同步块和同步函数之间的区别是什么。这段代码工作得很好,因为它避免了关键部分的错误

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){
    }
}
}
但是,如果我改用
public synchronized void run()
,它就不能同样/正确地工作。

根据:

同步方法在执行之前获取监视器(§17.1)

对于类(静态)方法,将使用与该方法的类的类对象关联的监视器

对于实例方法,将使用与之关联的监视器(调用该方法的对象)

synchronized(getClass())
块中,在
Class
对象上同步,因此
threadsynchronized
的所有实例都被序列化


当您使实例方法
同步时
,您仅在该实例上同步(该
引用)。

这两个方法在不同的对象上同步

synchronized(getClass()){…}
在类上进行同步,因此在两个线程实例中,一次只能有一个进入块

另一方面,
public synchronized void run(){…}
在实例上同步,因此这两个实例可以并行地进入块。只有当一个实例由多个线程共享时,该块才允许其中一个线程执行

对于普通实例方法,同步方法在实例上同步;对于静态方法,同步方法在类对象上同步


因此,如果您的
run()
方法可以重构为静态方法,那么
synchronized
method关键字将为您提供
synchronized(getClass()){…}
行为。

不,确实不会。一种情况是在类对象上同步,另一种情况是在实例上同步。而且您使用的是
静态m_计数
,因此在实例上同步将不起作用。请注意,非静态
同步的
方法在
上同步。您所实现的是一个有效的
静态同步
方法:它在
对象上进行同步。换句话说,
public void synchronized foo(){/}
类似于
public void foo(){synchronized(this){/}
谢谢,这非常有意义。我使用此引用而不是getClass()完成了相同的“不正确”行为。