【发布时间】:2018-05-16 13:43:10
【问题描述】:
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();
}}
请看上面的代码。为什么这里不会发生死锁?因为主线程在 func1 中并且想去 func2 但它不能因为 func2 被 ThreadSample 锁定。和 ThreadSample 也不能去 func1。所以我们应该面临僵局,但我们没有。
为什么?
【问题讨论】:
-
(也许我对死锁的理解不正确) func2 由 ThreadSample 线程调用,因此 func2 被 ThreadSample 线程锁定 func1 由主线程调用,因此 func1 被主线程锁定,当 ThreadSample 想要从 func2 出去它应该去 func1 但 func1 被主线程锁定,当主线程想要从 func1 出去时它应该去 func2 但 func2 被 ThreadSample 线程锁定。那么应该发生死锁吗?我的错在哪里?
-
如果你没有遇到死锁,那么你应该因为调用彼此的函数而导致堆栈溢出。
-
只有一个线程(新创建的或主线程)将处理 func1/func2 调用,但不会有任何问题。
-
不,我不是因为我在 func2 中造成的延迟
-
死锁(正如刘能所说,如下)至少需要两个不同的锁。死锁是当您有两个或更多线程时,它们都不能做任何事情(例如,获取锁),直到其中一个做某事(例如,释放一个锁)。最简单的情况(有时称为“致命拥抱”)是线程 A 已获得锁 1 并试图获得锁 2,而同时线程 B 已获得锁 2 并试图获得锁 1。线程将释放它已经获得的锁,直到它获得另一个锁,但是两个线程都无法获得另一个锁......
标签: java multithreading thread-safety deadlock synchronized