синхронизированное приращение значения int

1

Почему эта программа не отображает 2000 при каждом выполнении? Я знаю, что могу использовать AtomicInteger, но мне любопытно.

class Increment extends Thread{
     static Integer i=new Integer(0);

    public void run(){

        for(int j=1;j<=1000;j++){
            synchronized (i) {
                i++;
            }
        }

    }
}


public class Puzzle {
    public static void main(String args[]) {    
        Thread t1=new Increment();
        Thread t2=new Increment();
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        }catch (InterruptedException r){}
        System.out.println(Increment.i);    
    }    
}
  • 0
    У вас есть состояние гонки из-за использования i в качестве блокировки, измените синхронизированный (i) на Increment.class
  • 0
    Что я? Его не объявлено нигде.
Показать ещё 6 комментариев
Теги:
multithreading

1 ответ

10
Лучший ответ

Вы синхронизируетесь с изменяемой переменной i. Эта переменная меняет свое значение каждый раз, поэтому каждый раз, когда вы приобретаете блокировку на другом объекте. Каждый поток, таким образом, приобретает неподдерживаемый замок и может действовать одновременно, как если бы никакой синхронизации не было.

Занятие: используйте выделенный private static final Object lock = new Object() как блокировка.

  • 0
    Но ссылки
  • 0
    оооооо это умно Я не осознавал, что, хотя раньше я видел эту ошибку в SO - в основном именно поэтому рекомендуется использовать private final Object syncObject = new Object(); в качестве монитора вместо самого объекта, если объект может измениться (что в этом случае происходит с ++)
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню