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

时间:2018-10-09 05:07:05

标签: java multithreading concurrency synchronization executorservice

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,但是由于我遵循了同步机制,所以没有给出结果,但是如果我们在类级实例变量中创建一个锁对象,它的效果很好。正确的代码段位于下面

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);
    }
}

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

1 个答案:

答案 0 :(得分:2)

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

由于全局变量存储在堆上,并且被多个线程共享/可见,因此它们需要同步。

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

Here's关于Java内存模型的精彩文章