- При сотне итераций LockOne уже работает некорректно, но это и ожидалось, так как нет защиты от дедлока
- LockTwo не работает совсем и volatile не помогает, но это ожидаемо, так как одновременная работа потоков не гарантируется, а именно она необходима для данного лока
- PetersonLock сходу не работает корректно, но не из-за неверности алгоритма, а из-за спецификации jvm, ведь victim не изменяется в одном потоке и jvm не обязана проверять, изменялась ли эта переменная в другом, но это исправляется добавлением volatile, который гарантирует, что все потоки будут видеть последние изменения этой переменной
- LockZero (скорее всего после jit-компиляции свернется в пустую строчку): 1. Mutual exclusion: не выполняется, так как потоки работают независимо и нет условий, которые бы предотвратили одновременное попадание более одного потока в критическую секцию 2. Freedom from deadlock: выполняется, так как каждый поток не имеет условий приостановки своей работы, которые зависели бы от действий другого потока, то есть потоки выполняются независимо 3. Freedom from starvation: выполняется, так как из-за независимого от других потоков выполнения, каждый поток может зайти в критическую секцию в любой момент
- Для 3 пункта я решил использовать семафор. Корректность обеспечивается тем, что я установил ограничение на число потоков, которые допускаются до одновременной работы в критической секции, равное единице. Таким образом, код будет выполняться всегда последовательно, ведь семафор гарантирует то, что все потоки сверх установленного лимита будут ожидать своей очереди и, в моем случае, заходить в критическую секцию по одному, что аналогично выполнению в однопоточной среде
- В 4 пункте я просто использовал FilterLock (из учебника), который по-сути является обобщением PetersonLock и в теории должен корректно работать в многопоточной среде. Но на практике он не работает, так как jvm не гарантирует синхронизацию значений обычных переменных массива между потоками. Для корректной работы необходимо заменить int[] на CopyOnWriteArrayList или на AtomicInteger[]