Что произойдет, когда мы создадим объект блокировки (синхронизированный блок) внутри метода? - PullRequest
0 голосов
/ 09 октября 2018
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 голосов
/ 09 октября 2018

Локальные переменные хранятся в стеке потоков и создаются для каждого потока отдельно.Если локальная переменная не является примитивом, то сам экземпляр сохраняется в куче, но ссылка на объект сохраняется в стеке потоков.Вот почему локальные переменные являются поточно-ориентированными.

Поскольку глобальные переменные хранятся в куче и являются общими / видимыми для нескольких потоков, их необходимо синхронизировать.

Итак, в первом примере высоздаем новую блокировку для каждого потока, поэтому несколько потоков все еще могут получить к ней доступ.

Вот отличная статья о модели памяти Java

...