基于声明为“最终静态对象”的对象与简单“最终对象”的同步

时间:2015-07-07 18:31:54

标签: java multithreading concurrency static synchronized

我有一个关于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;
        }
    } 
}

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

如果将对象声明为static final,那么在该类的所有实例中只有一个锁共享。这意味着如果两个独立实例各自尝试在其上进行同步,则两个实例中只有一个能够一次获得锁定。

如果你将对象声明为final,那么每个类的实例都有一个锁的副本,所以如果每个类的两个独立实例都尝试获取锁,那么每个实例都会获取它们自己的锁,所以不涉及阻塞。但是,如果多个线程同时在类的一个实例上调用方法,那些线程将尝试获取相同的对象,因此一次只能执行一个线程。

希望这有帮助!

答案 1 :(得分:2)

使lock变量static使任何线程能够针对任何 ConcurrencySample块实例读取或写入消息,而不是仅阻塞另一个线程正在读取的特定实例。

它将基本上降低应用程序的并发级别:只有一个线程可以在任何实例上读取或写入消息,即使其他线程想要影响完全不同的实例。