Будут ли гарантированы потоки из ExecutorService для обновления локально объявленной параллельной хэш-карты? - PullRequest
3 голосов
/ 10 марта 2020
public void test() {

    List<Integer> integers = new ArrayList<>();
    for(int i = 0; i < 1000; i++) {
        integers.add(i);
    }

    Map<Integer, Integer> cache = new ConcurrentHashMap<>();
    ExecutorService pool = new ForkJoinPool(10);
    try {
        pool.submit(() -> integers.parallelStream().forEach(integer -> {
            String name = Thread.currentThread().getName();
            System.out.println("Foo " + name);
            cache.put(integer, integer);
        })).get();
    } catch (Exception e) {

    }

    System.out.println(cache);
}

Я прочитал, что вам понадобится переменная переменная, чтобы обеспечить предсказуемое распространение обновлений в другой поток. http://tutorials.jenkov.com/java-concurrency/volatile.html#variable -visibility-problem

В этом тестовом методе я не могу объявить одновременную хэш-карту "cache" как переменную "volatile", поскольку это локальная переменная, а не переменная экземпляра. Когда код попадет в строку System.out.println (кеш), будет ли гарантировано, что мой основной поток увидит все значения, которые были добавлены в «кеш» потоками ExecutorService?

1 Ответ

5 голосов
/ 10 марта 2020

Да, ваш код будет работать нормально. ConcurrentHashMap гарантирует, что все вставленные отображения будут выполняться потокобезопасным способом.

Вам не нужно заботиться о pool и cache - они, по сути, являются конечными переменными, и, как таковые, их значения однажды устанавливаются во время построения (перед запуском любого многопоточного кода ) больше не изменится.

Что может вас смущать, так это то, что при работе с неокончательными полями вам может понадобиться пометить их как volatile, если вы собираетесь их изменить и быть уверенными, что изменение правильно распространяется по всем потокам. Но, как сказано выше, обратите внимание, как в этом случае значение pool и caches никогда не изменяется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...