Невозможно воспроизвести - возможна ли детерминированная многопоточность Java?

Возможно ли запускать многопоточное Java-приложение детерминированным образом? Я имею в виду всегда одно и то же переключение потоков в двух разных запусках моего приложения.

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

Аналогичный случай, когда кто-то дает произвольное начальное число при использовании генератора случайных чисел, чтобы всегда получать одну и ту же «случайную» последовательность.


person sZpak    schedule 14.04.2016    source источник
comment
Планирование потоков контролируется ОС, а не Java.   -  person Andy Turner    schedule 14.04.2016
comment
Если вы достаточно тщательно синхронизировали свой код и зависите только от входных данных, доступных заранее, он всегда должен работать одинаково. (Или, наоборот, если результаты зависят от конкретного времени каждого запуска, вы недостаточно хорошо синхронизировали свой код.) В зависимости от того, что вам действительно нужно, вы также можете попробовать реализовать виртуальную машину Java в реальном времени.   -  person biziclop    schedule 14.04.2016
comment
@biziclop, если ваша программа так тщательно синхронизирована, скорее всего, вы потеряли по крайней мере некоторые преимущества использования нескольких потоков.   -  person Solomon Slow    schedule 14.04.2016
comment
Одна идея, которая витала в воздухе в течение довольно долгого времени (но я не знаю, насколько широкое внимание она получает), состоит в том, чтобы использовать виртуализированную среду, которая вызывает определенные сериализации многопоточного выполнения. Обычно цель состоит в том, чтобы протестировать многопоточный алгоритм (т. е. доказать, что все возможные сериализации будут вести себя правильно). Единственный пример, который я могу сейчас вспомнить, это github.com/google/thread-weaver — написан несколько лет назад некоторыми людьми из Google. Я не знаю, хороша ли она или чем она хороша в, но, возможно, на нее стоит взглянуть.   -  person Solomon Slow    schedule 14.04.2016
comment
@jameslarge Почти наверняка, да.   -  person biziclop    schedule 14.04.2016


Ответы (3)


Я не знаю ни одного практического способа сделать это.

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


1 — например, без ввода-вывода и без использования системных часов.

person Stephen C    schedule 14.04.2016
comment
Вам также потенциально придется реализовать GC. - person biziclop; 14.04.2016
comment
@biziclop - Может быть, нет. Единственные источники недетерминизма, связанные с сборщиком мусора, о которых вам нужно беспокоиться, — это хэш-коды идентификации, основанные на адресах памяти, и финализация. С обоими можно было бы справиться, я думаю. - person Stephen C; 15.04.2016

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

Если вам нужны детерминированные результаты, не используйте потоки.

person OldCurmudgeon    schedule 14.04.2016

Как цитирует OldCurmudgeon, это невозможно с многопоточностью.

Если вы решите использовать одиночный Thread, я предпочитаю newSingleThreadExecutor обычному Thread из-за гибкости и преимуществ newSingleThreadExecutor

Использовать

newSingleThreadExecutor из Executors

public static ExecutorService newSingleThreadExecutor()

Создает Executor, который использует один рабочий поток, работающий с неограниченной очередью. (Обратите внимание, однако, что если этот единственный поток завершится из-за сбоя во время выполнения до завершения работы, новый поток займет его место, если это необходимо для выполнения последующих задач.)

Задачи гарантированно выполняются последовательно, и в любой момент времени будет активным не более одной задачи. В отличие от эквивалентного в других отношениях newFixedThreadPool(1), возвращаемый исполнитель гарантированно не может быть переконфигурирован для использования дополнительных потоков.

Связанные с SE вопросы:

Разница между Executors.newFixedThreadPool(1) и Executors.newSingleThreadExecutor()

ExecutorService и обычный генератор потоков

person Ravindra babu    schedule 15.04.2016