当我们在方法中创建锁(同步块)对象时会发生什么?

What will happen when we create lock (Synchronized block) object inside a method?

public class SampleExecutorService {
    private static int count = 0;

    private void increment() {
        Object lock = new Object();
        synchronized (lock) {
            count++;
        }   
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        SampleExecutorService obj = new SampleExecutorService();
        Runnable task = obj::increment;

        for (int i = 0; i < 1000; i++) {
            executorService.submit(task);

        }
        executorService.shutdown();

        try {
            executorService.awaitTermination(2, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("count : " + count);
    }
}

上述程序的预期结果是 1000,但它没有给出该结果,因为我遵循了同步 mechanism.But 如果我们在 class 级实例变量中创建一个锁对象,它工作正常。正确的代码片段如下

public class SampleExecutorService {
    private static int count = 0;
    Object lock = new Object();
    private void increment() {
        //Object lock = new Object();
        synchronized (lock) {
            count++;
        }   
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        SampleExecutorService obj = new SampleExecutorService();
        Runnable task = obj::increment;

        for (int i = 0; i < 1000; i++) {
            executorService.submit(task);

        }
        executorService.shutdown();

        try {
            executorService.awaitTermination(2, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("count : " + count);
    }
}

我想知道,当我们在方法中创建锁对象时会发生什么?在方法内部创建锁对象和作为实例变量创建锁对象有什么区别?

局部变量存储在线程堆栈中,并为每个线程单独创建。如果局部变量不是原始变量,则实例本身存储在堆上,但对对象的引用存储在线程堆栈上。这就是为什么局部变量是线程安全的。

由于全局变量存储在堆上并且被多个线程 shared/visible 需要同步。

因此在您的第一个示例中,您为每个线程创建了新锁,因此多个线程仍然可以访问它。

Here's 一篇关于 Java 内存模型的优秀文章