Why does synchronization not work in the second code?
Asked Answered
A

3

5

Synchronization works correctly in this code:

    class PrintNumbers {
        synchronized public void display() {
            System.out.println("in display");
            for (int i = 0; i < 3; i++) {
                System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.getMessage();
                }
            }
            System.out.println("out of display");
        }
    }

    class MyThread implements Runnable {
        Thread t;
        PrintNumbers printNumbers;

        MyThread(PrintNumbers printNumbers, String s) {
            this.printNumbers = printNumbers;
            t = new Thread(this,s);
            t.start();
        }

        public void run() {
            printNumbers.display();
        }
    }

    class SyncExample {
        public static void main(String[] args) {
            PrintNumbers printNumbers = new PrintNumbers();

            new MyThread(printNumbers, "My Thread 1");
            new MyThread(printNumbers, "My Thread 2");
        }
    }

Output:

in display  
Thread name : My Thread 1 i= 0  
Thread name : My Thread 1 i= 1  
Thread name : My Thread 1 i= 2  
out of display
in display  
Thread name : My Thread 2 i= 0  
Thread name : My Thread 2 i= 1  
Thread name : My Thread 2 i= 2  
out of display

but not in this code:

    class PrintNumbers {
        synchronized public void display() {
            System.out.println("in display");
            for (int i = 0; i < 3; i++) {
                System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.getMessage();
                }
            }
            System.out.println("out of display");
        }
    }

    class MyThread implements Runnable {
        Thread t;
        PrintNumbers printNumbers;

        MyThread(String s) {
            this.printNumbers = new PrintNumbers();
            t = new Thread(this,s);
            t.start();
        }

        public void run() {
            printNumbers.display();
        }
    }

    class SyncExample {
        public static void main(String[] args) {
            new MyThread("My Thread 1");
            new MyThread("My Thread 2");
        }
    }

Output:

in display  
Thread name : My Thread 1 i= 0  
in display  
Thread name : My Thread 2 i= 0  
Thread name : My Thread 1 i= 1  
Thread name : My Thread 2 i= 1  
Thread name : My Thread 2 i= 2  
Thread name : My Thread 1 i= 2  
out of display  
out of display  

I cannot understand what difference wrt Synchronization does it make to initialize PrintNumbers in the Runnable MyThread and in the SyncExample class. Please explain.

Ackerley answered 8/10, 2016 at 9:11 Comment(5)
non-static synchronized methods synchronize on this.Swaney
2nd you need the display method static , they are locking 2 objects .Cooperative
You are using difference object of PrintNumbers and lock is at object level. That's why you are getting different output.Bickford
"When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object [...]. You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class."Misdo
Synchronization works on locking on object's monitor, and each object has its own monitor. If you create two PrintNumbers objects then you have two separate monitors so locking on one of them doesn't prevent other thread from locking on another (the one which it has access to).Theatrics
P
5

I cannot understand what difference wrt Synchronization does it make to initialize PrintNumbers in the Runnable MyThread and in the SyncExample class.

It doesn't. What does matter is that in your first example, you have only one PrintNumbers instance which both threads share. But in your second example, you have two separate PrintNumbers instances, one for each thread.

Since PrintNumbers#display synchronizes on the instance (synchronized instance methods synchronize on this), it only synchronizes within the instance, not across multiple instances.

When both threads share an instance, the two calls to display are serialized. But when the threads each have their own instance, the two calls to display are on separate instances, and thus there is no serialization of the calls, they can overlap.

Pasquinade answered 8/10, 2016 at 9:17 Comment(0)
C
4

Because in the second code each thread has its own PrintNumbers object so they work in parallel. In the first one they share the single PrintNumbers object and work with it in synchronized way.

PS. Remember that synchronized for non-static methods makes synchronization on object (for static methods on class).

Cretin answered 8/10, 2016 at 9:15 Comment(0)
B
3

It is working in both cases as it should. The difference is that in the first case you have a single object that is synchronized. In to second one you have two. They both are called only once so they are synchronized perfectly.

synchronized doesn't work between objects, only within one.

Bidentate answered 8/10, 2016 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.