简体   繁体   中英

Why synchronized function does not prevent entry? (JAVA)

I have 2 classes that I would like to create a deadlock with them. I tried to create two synchronized functions that read each other - and so the process will be stuck. But instead of the process being stuck, the functions continue to call each other. I did not understand why this happens, the synchronized keyword should stop a process from entering the function once there is another process in the same function.


MyRun:

public class MyRun extends Thread{
MyRun1 myRun1;

MyRun(){
    myRun1 = new MyRun1(this);
}

public synchronized boolean f(){
    System.out.println("MyRun.f()");
    while (!myRun1.f()){

    }

    return true;
}
}

MyRun2:

public class MyRun1 extends Thread {
MyRun myRun;

MyRun1(MyRun myRun){
    this.myRun = myRun;
}

public synchronized boolean f(){
    System.out.println("MyRun1.f()");
    while (!myRun.f()){}

    return true;
}
}

Main:

public static void main(String[] args){
    MyRun myRun = new MyRun();
    myRun.f();
}

output:

MyRun.f()
MyRun1.f()
MyRun.f()
MyRun1.f()
.
.
.
.
Exception in thread "main" java.lang.StackOverflowError

All of your code is running on the main thread, since you are not starting any additional threads. Therefore is doesn't matter whether your methods are synchronized or not, since the execution is sequential.

You have to call myRun.start() to start that Thread . And you have to override the run() method if you want the new thread to call myRun.f() .

You'll also have to start the other Thread (of type MyRun1 ) and override its run method.

PS, instead of extending the Thread class, it is a better practice for your classes to implement the Runnable interface and you pass instances of them to the Thread constructor.

Java synchronization is reentrant.

If a thread is executing a synchronized block, and the code inside that block directly or indirectly invokes code that tries to synchronize on the same object, it does not block.

Distilling it down:

synchronized (myRun) {
  synchronized (myRun1) {
    synchronized (myRun) {
      System.out.println("Hello");
    }
  }
}

Here, Hello will be printed, because the fact that myRun is already synchronized on doesn't block the inner block with synchronizes on it again.

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