Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗jvSpSyRc 198 of 322 menu
◀ ▶

Состояние гонки в Java

Гонка возникает, когда исход программы зависит от случайного чередования потоков, а общие данные не защищены. Один поток читает устаревшее значение, другой успевает записать своё, и часть обновлений пропадает.

Даже простое counter++ на уровне байткода распадается на загрузку, прибавление и сохранение. Между этими шагами соседний поток может выполнить ту же тройку действий с тем же стартовым числом.

Наглядный счетчик в объекте и два worker-потока:

class Tally { int value = 0; void bump() { value++; } } public class Main { public static void main(String[] args) throws InterruptedException { Tally tally = new Tally(); Runnable work = () -> { for (int i = 0; i < 500; i++) { tally.bump(); } }; Thread a = new Thread(work); Thread b = new Thread(work); a.start(); b.start(); a.join(); b.join(); System.out.println(tally.value); } }

Ожидали бы 1000, но печать часто показывает меньше. Чтобы убрать гонку, критический участок нужно выполнять так, будто внутри него работает только один поток.

Тот же сценарий с паузой между чтением и записью усиливает эффект:

class SlowTally { int value = 0; void bump() throws InterruptedException { int seen = value; Thread.sleep(1); value = seen + 1; } } public class Main { public static void main(String[] args) throws InterruptedException { SlowTally tally = new SlowTally(); Runnable work = () -> { for (int i = 0; i < 100; i++) { try { tally.bump(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } }; Thread a = new Thread(work); Thread b = new Thread(work); a.start(); b.start(); a.join(); b.join(); System.out.println(tally.value); } }

Класс Score с полем points и методом addOne() без синхронизации. Три потока по 200 вызовов. После join сравните результат с 600.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить