我正在阅读最初来自(我相信)IBM developerworks网站的线程教程。在其中,他们讨论了synchronized关键字以及同步代码块如何被实际对象锁定,而不是代码块本身。
例如,在下面的代码中,作者声明即使静态类'Thingie
的{{1}}方法被列为同步,下面定义的两个线程也可以调用{{1同时,因为他们为thingie使用不同的值。但是,如果thingie是静态的,那不就意味着它们使用相同的值吗?
变量名称是否只需要不同,即使它们指的是同一个对象?
setLastAccess
答案 0 :(得分:6)
您将静态方法与静态类混淆。如果setLastAccess
是静态方法,那么如果它被标记为synchronized
,它会锁定Class
中的ClassLoader
实例 - 那里每个装载机只是其中之一。如果该方法是静态的并且是同步的,则线程将锁定在同一对象上。
但是,在您的示例中,Thingie
类被标记为静态,而不是方法。 类上的static关键字表示Thingie
与外部SyncExample
类无关 - 它不意味着只有一个Thingie
的实例,它不会影响同步。因此,在您的示例中,当setLastAccess
标记为synchronized
时,它会锁定类Thingie
(this
)的实例。由于有两个实例(thingie1
和thingie2
),因此锁定在不同的对象上。显然,如果两个线程都在thingie1
中传递,那么它们都将锁定在同一个对象上。
这里有一些阅读:
答案 1 :(得分:3)
此代码:
class SomeClass {
public synchronized void setLastAccess(Date date) {
}
}
与:
相同class SomeClass {
public void setLastAccess(Date date) {
synchronized(this) {
}
}
}
这段代码:
class SomeClass {
public static synchronized void setLastAccess(Date date) {
}
}
与:
相同class SomeClass {
public static void setLastAccess(Date date) {
synchronized(SomeClass.class) {
}
}
}
答案 2 :(得分:0)
如果synchronized方法是实例方法,则对每个对象执行锁定。所以如果你有2个对象obj1和obj2,他们可以用自己的实例锁定来执行方法。
如果同步静态方法,则在类对象上完成锁定。因此,当第一个静态同步方法被执行时,该方法以及任何其他静态方法都无法执行。