我有一个关于Java并发的问题。如果我基于对象同步关键部分,则将该变量声明为final static Object
与简单地final Object
之间有什么区别。
我知道static
关键字将变量定义为属于该类,但我在多线程环境中的含义有些模糊。
请参阅下面的代码示例。目前我将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;
}
}
}
感谢您的帮助!
答案 0 :(得分:3)
如果将对象声明为static final
,那么在该类的所有实例中只有一个锁共享。这意味着如果两个独立实例各自尝试在其上进行同步,则两个实例中只有一个能够一次获得锁定。
如果你将对象声明为final
,那么每个类的实例都有一个锁的副本,所以如果每个类的两个独立实例都尝试获取锁,那么每个实例都会获取它们自己的锁,所以不涉及阻塞。但是,如果多个线程同时在类的一个实例上调用方法,那些线程将尝试获取相同的对象,因此一次只能执行一个线程。
希望这有帮助!
答案 1 :(得分:2)
使lock
变量static
使任何线程能够针对任何 ConcurrencySample
块实例读取或写入消息,而不是仅阻塞另一个线程正在读取的特定实例。
它将基本上降低应用程序的并发级别:只有一个线程可以在任何实例上读取或写入消息,即使其他线程想要影响完全不同的实例。