My java code does not synchronize

class MultiplyTable1 {
    synchronized void printTable(int n) {
        for (int i = 1; i <= 5; i++) {
            System.out.println(n * i);
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}

class ThreadOne1 extends Thread {
    MultiplyTable1 mtObj = new MultiplyTable1();

    public void run() {
        mtObj.printTable(2);
    }
}

class ThreadTwo2 extends Thread {
    MultiplyTable1 mtObj = new MultiplyTable1();

    public void run() {
        mtObj.printTable(100);
    }
}

public class ThreadDemoDupe {

    public static void main(String[] args) {
        ThreadOne1 t1 = new ThreadOne1();
        ThreadTwo2 t2 = new ThreadTwo2();
        t1.start();
        t2.start();
    }
}

OUTPUT:

100
2
200
4
300
6
8
400
10
500

What shall be my code to get the output as:

2
4
6
8
10
100
200
300
400
500

or

100
200
300
400
500
2
4
6
8
10

I don't have any more details to give.

Jon Skeet
people
quotationmark

You're creating two separate MultiplyTable1 objects. A synchronized instance method is effectively using:

synchronized (this) {
    ...
}

so if you call that method on two different objects, they can still run in parallel. To see the synchronization having an effect, you need to synchronize on a common object. You could do that by changing it to not synchronize on the MultiplyTable1 object itself, or you could just give both threads the same MultiplyTable1 object. For example:

class MultiplyTable1 {
    synchronized void printTable(int n) {
        for (int i = 1; i <= 5; i++) {
            System.out.println(n*i);
            try {
                Thread.sleep(500);
            }
            catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }
}

// Prefer implementing Runnable over extending Thread.
// In reality I'd only have a single class and parameterize
// the value passed to the printTable method, but...
class Runnable1 implements Runnable {
    private final MultiplyTable1 table;

    Runnable1(MultiplyTable1 table) {
        this.table = table;
    }

    @Override public void run() {
        table.printTable(2);
    }
}

class Runnable2 implements Runnable {
    private final MultiplyTable1 table;

    Runnable2(MultiplyTable1 table) {
        this.table = table;
    }

    @Override public void run() {
        table.printTable(100);
    }
}

public class ThreadDemoDupe {
    public static void main(String[] args) {
        MultiplyTable1 table = new MultiplyTable1();
        Thread t1 = new Thread(new Runnable1(table));
        Thread t2 = new Thread(new Runnable2(table));
        t1.start();
        t2.start();
    }
}

people

See more on this question at Stackoverflow