为什么在这种情况下不会发生死锁
why doesn't deadlock occur in this situation
public class TestClass {
public synchronized void func1() throws InterruptedException {
System.out.println("func1");
long a = System.nanoTime();
func2();
}
public synchronized void func2() throws InterruptedException {
System.out.println("func2");
long a = System.nanoTime();
while (System.nanoTime() - a < 10000000) {
;
}
func1();
} }
public class ThreadSample extends Thread {
TestClass testClass;
public ThreadSample(TestClass testClass)
{
this.testClass = testClass;
}
@Override
public void run() {
try {
testClass.func2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}}
public class Main {
public static void main(String[] args) throws InterruptedException {
TestClass testClass = new TestClass();
ThreadSample threadSample = new ThreadSample(testClass);
threadSample.start();
testClass.func1();
}}
请看上面的代码。为什么这里不发生死锁?因为Main线程在func1里面,想去func2但是去不了,因为func2被ThreadSample锁住了。而ThreadSample也不能去func1。所以我们应该面临僵局,但我们没有。
为什么?
只有在有多个锁时才会出现死锁
在这种情况下,func2
和 func1
在同一个 lock
监视器(TestClass
的实例)上同步。一旦一个线程获得了这个锁,其他线程将被阻塞,直到它释放锁。
假设main thread
已经进入了func1
,也就是说它已经获得了锁,其他线程不能同时调用func2
时间。因为 fun1
和 fun2
使用的是同一个锁!而在 fun1
中,这个线程可以调用 fun2
因为 synchronized
块是可重入的。
您可以用 sleep
替换 func2()
方法,如下所示,以锁定 testClass
对象:
public synchronized void func2() throws InterruptedException {
System.out.println("func2");
long a = System.nanoTime();
Thread.sleep(1000000000000L);
//func1();
}
现在,threadSample
线程首先获得锁(启动后)在 func2
中等待(持有 testClass
对象上的锁)因此 main
线程可以'甚至进入 func1()
等待锁定同一对象。
public class TestClass {
public synchronized void func1() throws InterruptedException {
System.out.println("func1");
long a = System.nanoTime();
func2();
}
public synchronized void func2() throws InterruptedException {
System.out.println("func2");
long a = System.nanoTime();
while (System.nanoTime() - a < 10000000) {
;
}
func1();
} }
public class ThreadSample extends Thread {
TestClass testClass;
public ThreadSample(TestClass testClass)
{
this.testClass = testClass;
}
@Override
public void run() {
try {
testClass.func2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}}
public class Main {
public static void main(String[] args) throws InterruptedException {
TestClass testClass = new TestClass();
ThreadSample threadSample = new ThreadSample(testClass);
threadSample.start();
testClass.func1();
}}
请看上面的代码。为什么这里不发生死锁?因为Main线程在func1里面,想去func2但是去不了,因为func2被ThreadSample锁住了。而ThreadSample也不能去func1。所以我们应该面临僵局,但我们没有。
为什么?
只有在有多个锁时才会出现死锁
在这种情况下,func2
和 func1
在同一个 lock
监视器(TestClass
的实例)上同步。一旦一个线程获得了这个锁,其他线程将被阻塞,直到它释放锁。
假设main thread
已经进入了func1
,也就是说它已经获得了锁,其他线程不能同时调用func2
时间。因为 fun1
和 fun2
使用的是同一个锁!而在 fun1
中,这个线程可以调用 fun2
因为 synchronized
块是可重入的。
您可以用 sleep
替换 func2()
方法,如下所示,以锁定 testClass
对象:
public synchronized void func2() throws InterruptedException {
System.out.println("func2");
long a = System.nanoTime();
Thread.sleep(1000000000000L);
//func1();
}
现在,threadSample
线程首先获得锁(启动后)在 func2
中等待(持有 testClass
对象上的锁)因此 main
线程可以'甚至进入 func1()
等待锁定同一对象。