简体   繁体   中英

What happens when a synchronized method is called by a thread via another class?

Feels good to be a part of this community. Have read lot of answers clearing my doubts for many ques but didn't find one for this one. I know how the synchronization works in Java, but confused to see a deviated behavior when the synchronized method is being called by the the threads via another class.

PSB what I tried:

Class A with synchronzed method "meth1".

package threadinterview;

public class A {
public synchronized void meth1()
{
    for(int i=0; i<3; i++)
    {
        System.out.println("meth1: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted: " + Thread.currentThread().getName());
        }
    }
}

Class B with non-synhronized method "meth2"

package threadinterview;

public class B {
public void meth2() {
    A a1 = new A();
    a1.meth1();
}
}

Main class to run the project

package threadinterview;
public class ThreadImpl {
public static void main(String[] args) {
    final B b1 = new B();
    final B b2 = new B();

    new Thread(new Runnable() {

        @Override
        public void run() {
            b1.meth2();
        }
    }).start();

    new Thread(new Runnable() {

        @Override
        public void run() {
            b1.meth2();
        }
    }).start();
}
}

Now in this scenario, even though I am ultimately running the synchronized method, I can't see the effect of synchronization. Here what I get when I run the program:

meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1

And if I make the synchronized method static as well, then I get the class level lock and can see the synchronization effect in place. I seriously don't understand why the class level locking works but the object level doesn't work in this case.

Each call to

public void meth2() {
    A a1 = new A();
    a1.meth1();
}

creates a new A object. synchronized on the method synchronizes on this , the object itself. Therefore, you are synchronizing on different objects. One synchronized call doesn't prevent the other synchronized call as both threads get different monitors.

I think you are misunderstanding what the 'synchronization effect' is. In your example, you are calling B.meth2() from two separate threads. This method creates a new instance of class A and then calls A.meth1() . Now whatever locking you are trying to enforce on meth1() (which is not really clear from your example or description), it's irrelevant because you are calling it on two different instances of class A , ie, you are implicitly using two different locks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM