为什么同步功能不会阻止进入? (JAVA)

时间:2019-01-14 08:37:36

标签: java

我有2个我想与他们创建死锁的类。 我试图创建两个相互读取的同步函数-因此该过程将卡住。 但是,函数不会继续卡住,而是继续互相调用。 我不明白为什么会这样,一旦同一个函数中存在另一个进程,则synced关键字应该阻止进程进入该函数。


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;
}
}

主要

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

输出:

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

2 个答案:

答案 0 :(得分:3)

所有代码都在主线程上运行,因为您没有启动任何其他线程。因此,无论您的方法是否为synchronized都无关紧要,因为执行是顺序执行的。

您必须致电myRun.start()来启动Thread。如果要新线程调用run(),则必须重写myRun.f()方法。

您还必须启动另一个Thread(类型为MyRun1run

PS,而不是扩展Thread类,对于您的类来说,实现Runnable接口并将它们的实例传递给Thread构造函数是一种更好的做法。

答案 1 :(得分:0)

Java同步是可重入的。

如果线程正在执行同步块,并且该块中的代码直接或间接调用试图在同一对象上进行同步的代码,则它不会阻塞。

将其蒸馏掉:

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

此处将打印Hello,因为myRun已经同步的事实并不会阻止内部块再次同步。