我正在阅读最初来自(我相信)IBM developerWorks网站的线程教程。在其中,他们讨论了synced关键字以及实际对象如何锁定同步的代码块,而不是代码块本身。
例如,在作者下面的代码中指出,即使静态类“Thingie
”的setLastAccess
方法被列为同步方法,但在其下方定义的两个线程仍可以同时调用setLastAccess
,因为它们为thingie使用了不同的值。但是,如果事情是静态的,那不意味着他们使用的是相同的值吗?
即使变量名称指向相同的对象,是否也需要仅使用不同的名称?
public class SyncExample {
public static class Thingie {
private Date lastAccess;
public synchronized void setLastAccess(Date date) {
this.lastAccess = date;
}
}
public static class MyThread extends Thread {
private Thingie thingie;
public MyThread(Thingie thingie) {
this.thingie = thingie;
}
public void run() {
thingie.setLastAccess(new Date());
}
}
public static void main() {
Thingie thingie1 = new Thingie(),
thingie2 = new Thingie();
new MyThread(thingie1).start();
new MyThread(thingie2).start();
}
}
最佳答案
您正在将静态方法与静态类混淆。如果setLastAccess
是静态方法,则将其标记为synchronized
,它将锁定Class
中的ClassLoader
实例-每个加载程序仅包含其中一个。如果该方法是静态且同步的,则线程将锁定在同一对象上。
但是,在您的示例中,Thingie
类被标记为静态,而不是方法。类上的static关键字表示Thingie
不受外部SyncExample
类的束缚-并不意味着Thingie
只有一个实例,并且不影响同步。因此,在您的示例中,当setLastAccess
标记为synchronized
时,它会锁定类Thingie
(this
)的实例。由于有两个实例(thingie1
和thingie2
),因此锁位于不同的对象上。显然,如果两个线程都以thingie1
传递,则它们都将锁定在同一对象上。
这里是一些阅读: