使用本地锁而不是共享锁进行同步是否安全?

sac*_*tiw 2 java synchronization

我将尝试通过以下3个案例来解释这个问题.情况I:我使用共享锁进行同步,使用类似这样的方法:


         private static final String SHARED_LOCK = "shared_lock";
         private static int i = 0;
         private static int j = 0;
    void increment() {
        synchronized (SHARED_LOCK) {
            i++;
            j++;
        }
    }
Run Code Online (Sandbox Code Playgroud)

它工作正常.

情况II:现在我在这里更改的是使用共享锁而不是使用本地锁通过执行以下操作:


         private static int i = 0;
         private static int j = 0;
    void increment() {
        final String LOCAL_LOCK = "local_lock";
                  synchronized (LOCAL_LOCK) {
            i++;
            j++;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我发现代码仍然正常工作,同步仍然有效.

案例III:但是当我将本地locl更改为:

final String LOCAL_LOCK = new String("local_lock");
Run Code Online (Sandbox Code Playgroud)

然后同步就消失了.所以看起来在CASE II中本地锁能够提供同步,因为Java为我们自动执行的字符串文字的实现,但在CASE III中,因为我每次都明确地创建一个新的字符串,因此没有发生同步.

所以回到我原来的问题.有谁觉得CASE II不是实现同步的正确方法吗?如果是,你还可以提一下为什么?

在此先感谢,SacTiw.

Abh*_*kar 8

锁用于在单独的线程中运行的代码之间提供同步.如果你使用本地锁,每个线程将拥有自己的锁对象副本(在线程的堆栈中),它将锁定它,因此不会有同步.

它仅适用于您的情况,因为String interning.如果使用final Object LOCAL_LOCK = new Object();它将无法正常工作.

因此,锁应始终在线程之间共享.