Предоставляет ли Java-модель памяти - прежде чем гарантировать взаимодействие потоков пула? В частности, будет делать записи, сделанные потоком рабочего потока потока, до того, как конец работы элемента из рабочей очереди будет видимым для рабочего потока, следующего за ним после очередного элемента из очереди?. Модель памяти Java происходит раньше, чем обеспечивается взаимодействие пула потоков.
Спецификация (я лично считаю этот FAQ полезным: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization) говорится, что «Вызов, чтобы начать() на поток происходит до каких-либо действий в запущенном потоке.» Или проще говоря, любая память пишет вы делаете перед запуском потока будет выполняться до и видимым для метода run() начальный поток будет выполняться. Для пула потоков он отличается от другого, start() обычно запускается до того, как вы сделаете запись. Рассмотрим простой рабочий процесс, где контекст объекта мутантный и передается к следующему действию:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
private static class Container<T> {
private T value;
public T get() {
return value;
}
public void set(T newValue) {
value = newValue;
}
}
public static void main(String[] args) {
final Container<Integer> sharedObject = new Container<>();
final ExecutorService executor = Executors.newFixedThreadPool(10);
// SKIPPED: pre-warm the executor so all worker threads are start()'ed
final Runnable read =() -> System.out.println("Got " + sharedObject.get());
Runnable write =() -> {
sharedObject.set(35);
executor.execute(read);
};
executor.execute(write);
// SKIPPED: wait until done
}
}
ли запись в sharedObject.value
write.run()
по гарантированно видны (не спрашивая об упорядочении, это очевидно) к read.run()
?
(PS: Я понимаю, что делает value
volatile
действительно обеспечивает эту гарантию)
Update (дополняет ответ): Пакета резюме документации java.util.concurrent
суммирует непротиворечивость гарантию памяти, предоставляемую языком и продолженную в рамках : https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
Я не следую за вами - ваше заключение противоположно цитированной вами цитате ... В примере op определенно есть отношение hb между 'sharedObject.set (35)' и 'println'. Возможно, вы упустили тот факт, что вторая задача добавляется в очередь * из первой задачи *, а не в основной поток. – assylias
@assylias Вы правы, я пропустил этот факт. Поскольку формулировка моего ответа предполагает, я говорю о двух независимо добавленных задачах, а не о одной задаче, представляющей другую. – Andreas
Спасибо, что заметили несоответствие между моим вопросом и примером. Пример - это то, о чем я хотел знать, но не мог понять вопрос, это было бы: писать действия в 'write', сделанные до отправки' read', видимого в поток 'read'. – Pavel