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);
}
I read that you will need to have volatile variable to ensure updates to a variable are propagated predictably to other thread. http://tutorials.jenkov.com/java-concurrency/volatile.html#variable-visibility-problems
In this test method I cannot declare the "cache" concurrent hashmap as a "volatile" variable since it is a local variable not an instance variable. When the code gets to System.out.println(cache) line, will it guaranteed that my main thread will see all the values that were added to "cache" by ExecutorService threads?
Yes, your code will work fine. The ConcurrentHashMap
guarantees that all the inserted mappings will happen in a thread-safe manner.
You don't need to care about pool
and cache
-- they're effectively final variables, and as such, their values once set at construction time (before you start any multi-threaded code) won't change anymore.
What may be confusing you is that when dealing with non-final fields, you may need to mark them as volatile
if you intend to change them and to be sure that the change is correctly propagated across threads. But as said above, notice how in this case the value of pool
and caches
is never changed.