java中的同步关键字和静态类
我在读一本线程教程,它最初来自(我相信)IBMdeveloperWorks站点。在这篇文章中,他们讨论了synchronized关键字,以及同步代码块是如何被实际对象而不是代码块本身锁定的 例如,在下面的代码中,作者指出,即使静态类“java中的同步关键字和静态类,java,multithreading,synchronize,Java,Multithreading,Synchronize,我在读一本线程教程,它最初来自(我相信)IBMdeveloperWorks站点。在这篇文章中,他们讨论了synchronized关键字,以及同步代码块是如何被实际对象而不是代码块本身锁定的 例如,在下面的代码中,作者指出,即使静态类“Thingie”的setLastAccess方法被列为synchronized,下面定义的两个线程也可以同时调用setLastAccess,因为它们对Thingie使用不同的值。但是如果东西是静态的,这不意味着它们使用相同的值吗 变量名是否只需要不同,即使它们引用的
Thingie
”的setLastAccess
方法被列为synchronized,下面定义的两个线程也可以同时调用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
,它将锁定ClassLoader
中的Class
实例——每个加载程序只有一个实例。如果该方法是静态和同步的,那么线程将锁定在同一对象上
但是,在您的示例中,Thingie
类被标记为静态,而不是方法。类上的static关键字表示Thingie
未绑定到外部SyncExample
类——这并不意味着只有一个Thingie
实例,也不影响同步。因此,在您的示例中,当setLastAccess
标记为synchronized
时,它将锁定类Thingie
(this
)的实例。由于存在两个实例(thingie1
和thingie2
),因此锁位于不同的对象上。显然,如果两个线程都传入thingie1
,那么它们都将锁定在同一个对象上
以下是一些阅读材料:
setLastAccess
是一个静态方法,那么如果它被标记为synchronized
,它将锁定ClassLoader
中的Class
实例——每个加载程序只有一个实例。如果该方法是静态和同步的,那么线程将锁定在同一对象上
但是,在您的示例中,Thingie
类被标记为静态,而不是方法。类上的static关键字表示Thingie
未绑定到外部SyncExample
类——这并不意味着只有一个Thingie
实例,也不影响同步。因此,在您的示例中,当setLastAccess
标记为synchronized
时,它将锁定类Thingie
(this
)的实例。由于存在两个实例(thingie1
和thingie2
),因此锁位于不同的对象上。显然,如果两个线程都传入thingie1
,那么它们都将锁定在同一个对象上
以下是一些阅读材料:
class SomeClass {
public synchronized void setLastAccess(Date date) {
}
}
同:
class SomeClass {
public void setLastAccess(Date date) {
synchronized(this) {
}
}
}
class SomeClass {
public static void setLastAccess(Date date) {
synchronized(SomeClass.class) {
}
}
}
该代码:
class SomeClass {
public static synchronized void setLastAccess(Date date) {
}
}
同:
class SomeClass {
public void setLastAccess(Date date) {
synchronized(this) {
}
}
}
class SomeClass {
public static void setLastAccess(Date date) {
synchronized(SomeClass.class) {
}
}
}
此代码:
class SomeClass {
public synchronized void setLastAccess(Date date) {
}
}
同:
class SomeClass {
public void setLastAccess(Date date) {
synchronized(this) {
}
}
}
class SomeClass {
public static void setLastAccess(Date date) {
synchronized(SomeClass.class) {
}
}
}
该代码:
class SomeClass {
public static synchronized void setLastAccess(Date date) {
}
}
同:
class SomeClass {
public void setLastAccess(Date date) {
synchronized(this) {
}
}
}
class SomeClass {
public static void setLastAccess(Date date) {
synchronized(SomeClass.class) {
}
}
}
如果同步方法是实例方法,则对每个对象执行锁定。因此,如果您有两个对象obj1和obj2,它们可以在自己的实例被锁定的情况下执行方法
如果一个静态方法是同步的,那么锁定就在类对象上完成。因此,在执行第一个静态同步方法时,无法执行该方法以及任何其他静态方法。如果同步方法是实例方法,则对每个对象执行锁定。因此,如果您有两个对象obj1和obj2,它们可以在自己的实例被锁定的情况下执行方法
如果一个静态方法是同步的,那么锁定就在类对象上完成。因此,在执行第一个静态同步方法时,无法执行该方法以及任何其他静态方法。我确信它不依赖于变量的名称。同步是对实际对象的调用,而不是对变量的调用。我的回答对@larryq有帮助吗?如果是这样的话,请接受它。我确信它不依赖于变量的名称。同步是对实际对象的调用,而不是对变量的调用。我的回答对@larryq有帮助吗?如果是的话,请接受。我感谢你的解释。然而,假设Thingie是一个静态类,那么是否可以有两个实例(thingie1和thingie2)?如果不是,这是否意味着对setLastAccess()的两个(同步)调用是从同一Thingie实例调用的?不确定您是否阅读了我的答案@larryq。
static
关键字并不表示单个实例。阅读我答案中的第二段和上面的“嵌套类”链接。格雷-非常感谢您的澄清和链接。我之前对嵌套静态类表示什么的误解。我认为这意味着它是外部类的一个静态成员(虽然是一个类),因此不能直接实例化——或者至少,这样做只会返回一个绑定到外部类的实例。我错了。我道歉,格雷,你现在得到了照顾。我感谢你的解释。然而,假设Thingie是一个静态类,那么是否可以有两个实例(thingie1和thingie2)?如果不是,这是否意味着对setLastAccess()的两个(同步)调用是从同一Thingie实例调用的?不确定您是否阅读了我的答案@larryq。static
关键字并不表示单个实例。阅读我答案中的第二段和上面的“嵌套类”链接。格雷-非常感谢您的澄清和链接。我之前对嵌套静态类repr的误解