【问题标题】:Synchronization based on an object declared as "final static Object" vs. simply "final Object" [duplicate]基于声明为“最终静态对象”的对象与简单的“最终对象”进行同步 [重复]
【发布时间】:2015-07-07 18:31:54
【问题描述】:

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

感谢您的帮助!

【问题讨论】:

  • 没什么特别的意思,就是你说的。如果您将lock 声明为static,它将由该类的所有实例共享,因此对任何实例的setMessage()/getMessage() 调用将阻止所有其他实例。看到你操作的message 字段不是static,锁也没有理由应该是static。

标签: java multithreading concurrency static synchronized


【解决方案1】:

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

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

希望这会有所帮助!

【讨论】:

  • 正是我需要的。谢谢。
【解决方案2】:

创建lock 变量static 将使任何线程针对ConcurrencySample 的任何 实例读取或写入消息,而不是仅在正在执行的特定实例上阻塞。被另一个线程读取。

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

【讨论】:

    猜你喜欢
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    相关资源
    最近更新 更多