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()完成了相同的“不正确”行为。