Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

synchronized increment an int value

Why this program doesn`t display 2000 at every execution? I know that I can use AtomicInteger, but I am curious.

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);    
    }    
}
like image 582
lucian.marcuta Avatar asked Dec 19 '22 12:12

lucian.marcuta


1 Answers

You synchronize on a mutable variable i. This variable changes its value each time, therefore each time you acquire a lock on another object. Each thread thus acquires a non-contended lock and can proceed simultaneously, as if no synchronization was in place.

Lesson: use a dedicated private static final Object lock = new Object() as a lock.

like image 168
Marko Topolnik Avatar answered Dec 22 '22 02:12

Marko Topolnik