基于声明为 "final static Object" 的对象的同步与简单的 "final Object"
Synchronization based on an object declared as "final static Object" vs. simply "final Object"
我有一个关于 Java 并发的问题。如果我同步一个基于对象的关键部分,将该变量声明为 final static Object
与简单地 final Object
.
之间有什么区别
我明白 static
关键字定义一个属于 class 的变量,但我对它在多线程环境中的含义有点模糊。
请参考下面的代码示例。目前我将 lock
对象声明为 private final Object lock = new Object()
,如果我添加 static
关键字会有什么不同?
class ConcurrencySample {
private String message = null;
private final Object lock = new Object();
//private final static Object lock = new Object();
public void setMessage(String msg) {
synchronized (lock) {
message = msg;
}
}
public String getMessage() {
synchronized (lock) {
String temp = message;
message = null;
return temp;
}
}
}
感谢您的帮助!
使 lock
变量 static
将使任何针对 ConcurrencySample
的 any 实例读取或写入消息的线程阻塞,因为反对仅在另一个线程正在读取的特定实例上阻塞。
它基本上会降低应用程序的并发级别:只有一个线程可以在任何实例上读取或写入消息,即使其他线程想要影响完全不同的实例也是如此。
如果您将对象声明为 static final
,则 class 的所有实例共享一个锁。这意味着如果两个独立的实例各自尝试在其上同步,则两个实例中只有一个能够同时获得锁。
如果您将对象声明为 final
,那么 class 的每个实例都有一个锁副本,因此如果 class 的两个独立实例各自尝试获得锁,他们每个人都获得自己的锁,所以不涉及阻塞。但是,如果多个线程都同时调用 class 的一个实例上的方法,这些线程将尝试获取同一个对象,因此一次只能有一个线程继续进行。
希望对您有所帮助!
我有一个关于 Java 并发的问题。如果我同步一个基于对象的关键部分,将该变量声明为 final static Object
与简单地 final Object
.
我明白 static
关键字定义一个属于 class 的变量,但我对它在多线程环境中的含义有点模糊。
请参考下面的代码示例。目前我将 lock
对象声明为 private final Object lock = new Object()
,如果我添加 static
关键字会有什么不同?
class ConcurrencySample {
private String message = null;
private final Object lock = new Object();
//private final static Object lock = new Object();
public void setMessage(String msg) {
synchronized (lock) {
message = msg;
}
}
public String getMessage() {
synchronized (lock) {
String temp = message;
message = null;
return temp;
}
}
}
感谢您的帮助!
使 lock
变量 static
将使任何针对 ConcurrencySample
的 any 实例读取或写入消息的线程阻塞,因为反对仅在另一个线程正在读取的特定实例上阻塞。
它基本上会降低应用程序的并发级别:只有一个线程可以在任何实例上读取或写入消息,即使其他线程想要影响完全不同的实例也是如此。
如果您将对象声明为 static final
,则 class 的所有实例共享一个锁。这意味着如果两个独立的实例各自尝试在其上同步,则两个实例中只有一个能够同时获得锁。
如果您将对象声明为 final
,那么 class 的每个实例都有一个锁副本,因此如果 class 的两个独立实例各自尝试获得锁,他们每个人都获得自己的锁,所以不涉及阻塞。但是,如果多个线程都同时调用 class 的一个实例上的方法,这些线程将尝试获取同一个对象,因此一次只能有一个线程继续进行。
希望对您有所帮助!