Я нашел много вопросов и ответов, связанных с видимостью, синхронизацией и многопоточностью, но ни один из них не отвечал моему конкретному варианту использования (или, может быть, я просто отстой в поиске ;-), поэтому я задам новый вопрос и надеюсь, что какая-то щедрая душа просветит меня:)
Мой вопрос: учитывая приведенный ниже код, будет ли доступ к полям элементов WorkItem в главном потоке правильно отражать любые изменения, внесенные в них рабочими потоками пула потоков?
Мое подозрение - "НЕТ", поскольку это похоже на передачу массива некоторых значений вокруг и просто синхронизацию по ссылке на массив, но не по отдельным элементам ... должна быть причина, по которой существуют классы, такие как AtomicReferenceArray в JDK и почему они используют getVolatile () / setVolatile () при доступе к отдельным элементам.
package com.voipfuture.voipmng.monitoring;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class IsThisThreadSafe
{
public static class WorkItem { public String field1,field2; /* etc. */ }
public static void main(String[] args) throws InterruptedException
{
final ExecutorService service = Executors.newFixedThreadPool(5);
final List<WorkItem> items = List.of(new WorkItem(), new WorkItem());
final CountDownLatch finished = new CountDownLatch(items.size());
for (WorkItem item : items)
{
service.submit(() ->
{
try
{
synchronized (item)
{
// mutate object
item.field1 = "test";
}
}
finally
{
finished.countDown();
}
});
}
finished.await();
for (WorkItem item : items)
{
// will this make sure all changes done inside
// threadpool worker threads are visible here ?
synchronized (item)
{
// do stuff with work item
System.out.println(item.field1);
}
}
}
}