Alexandre Krabbe
Alexandre Krabbe

Reputation: 781

Why is Java synchronized not working as expected?

I'm trying to figure out how synchronized methods work. From my understanding I created two threads T1 and T2 that will call the same method addNew, since the method is synchronized shouldn't it execute all the iterations of the for loop for one thread and then the other? The output keeps varying, sometimes it prints it right, other times it prints values from T1 mixed with T2 values. The code is very simple, can someone point out what am I doing wrong? Thank you.

public class Main {
    public static void main(String[] args) {
        Thread t1 = new Thread(new A());
        Thread t2 = new Thread(new A());
        t1.setName("T1");
        t2.setName("T2");
        t1.start();
        t2.start();
    }
}

public class B {
    public synchronized void addNew(int i){
        Thread t = Thread.currentThread();
        for (int j = 0; j < 5; j++) {
            System.out.println(t.getName() +"-"+(j+i));
        }
    }
}

public class A extends Thread {
    private B b1 = new B();

    @Override
    public void run() {
        b1.addNew(100);
    }
}

Upvotes: 3

Views: 5981

Answers (3)

Atul P.
Atul P.

Reputation: 1

try this :

public class Main {
    public static void main(String[] args) {
        A a = new A();
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(a);
        t1.setName("T1");
        t2.setName("T2");
        t1.start();
        t2.start();
    }
}

 class B {
    public synchronized void addNew(int i){
        Thread t = Thread.currentThread();
        for (int j = 0; j < 5; j++) {
            System.out.println(t.getName() +"-"+(j+i));
        }
    }
}

 class A extends Thread {
    private B b1 = new B();

    @Override
    public void run() {
        b1.addNew(100);
    }
}

Upvotes: 0

Kayaman
Kayaman

Reputation: 73578

Both A objects have their own B object. You need them to share a B so the synchronization can have an effect.

Upvotes: 3

Brian Goetz
Brian Goetz

Reputation: 95554

Each A instance has its own B instance. The method addNew is an instance method of B. Therefore, the lock acquired implicitly during calls to addNew is the lock on the receiver B instance. Each thread is calling addNew on a different B, and therefore locking on different locks.

If you want all B instances to use a common lock, create a single shared lock, and acquire it in the body of addNew.

Upvotes: 9

Related Questions