Я хочу реализовать алгоритм топосортировки, который можно выполнять параллельно над графиком в Java с использованием потоков. В частности, алгоритм, найденный в этой статье здесь .
Важной частью этого алгоритма для этого вопроса является то, что значение расписания, которое мы храним для каждого узла, обновляется следующим образом: если поток встречает узел на графике, он будет читать его текущее значение. Если поток имеет более высокое значение, он заменит его и продолжит работу. В противном случае это остановится.
Мне нужно иметь возможность выполнять запись и чтение для определенного узла за одну атомарную операцию. Я хочу представить значение в виде значения на карте с идентификатором ключа int (для каждого узла). Однако из того, что я вижу, методы синхронизации для Карт в Java, кажется, либо блокируют только записи, либо блокируют всю карту. Если вся карта заблокирована, производительность также может быть однопоточной. Если чтение не заблокировано, я могу получить неправильное поведение.
Моя цель - блокировать только определенный индекс. Если два потока хотят читать и обновлять разные узлы, это нормально, но если два потока сталкиваются с одним и тем же узлом, мне нужно убедиться, что каждая операция read -> check -> update or stop
происходит атомарно. Конкретный случай, которого я хочу избежать:
Thread_1 (val 5) read g_1 -> value is 3, trigger update
Thread_2 (val 4) read g_1 -> value is 3, trigger update
Thread_1 (val 5) lock and update g_1 -> g_1 value is 5
Thread_2 (val 4) lock and update g_1 -> g_1 value is 4
Вместо этого я собираюсь сделать:
Thread_1 (val 5) lock g_1
Thread_2 (val 4) wait for g_1
Thread_1 (val 5) read g_1 -> value is 3, update g_1 -> g_1 value is 5
Thread_1 (val 5) release g_1
Thread_2 (val 4) lock g_1
Thread_2 (val 4) read g_1 -> value is 5, do nothing
Thread_2 (val 4) release g_1