【发布时间】:2020-05-10 08:11:21
【问题描述】:
我有两段代码。第一个使用同步块,它会导致死锁,这是完全可以理解的。
在第二个代码中,我尝试重新创建相同的问题,但这次使用Reentrant locks。但是第二个代码在某些情况下不会导致死锁。在某些情况下会出现死锁,控制台中不会打印任何内容。
你能解释一下为什么吗?我没有正确使用Reentrant locks 吗?
导致死锁的代码
package com.practice.multithreading;
public class DeadlockYoutube {
public static void main(String[] args) {
final String resource1="Printer";
final String resource2="Scanner";
Runnable run1=()->{
synchronized (resource1) {
System.out.println(Thread.currentThread().getName()+" : locked-> "+resource1);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(resource2) {
System.err.println(Thread.currentThread().getName()+" : locked-> "+resource2);
}
}
};
Runnable run2=new Runnable(){
@Override
public void run() {
synchronized (resource2) {
System.out.println(Thread.currentThread().getName()+" : locked-> "+resource2);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(resource1) {
System.err.println(Thread.currentThread().getName()+" : locked-> "+resource1);
}
}
}
};
Thread thread1= new Thread(run1);
thread1.setName("Desktop");
Thread thread2=new Thread(run2);
thread2.setName("Laptop");
thread1.start();
thread2.start();
}
}
具有可重入锁的相同代码/不会导致死锁
package com.practice.multithreading;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//not working as expected
public class DeadlockYoutubeReentrantLocks {
public static void main(String[] args) {
final String resource1 = "Printer";
final String resource2 = "Scanner";
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
Runnable run1 = () -> {
lock1.lock();
lock2.lock();
System.out.println(Thread.currentThread().getName() + " : locked-> " + resource1);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println(Thread.currentThread().getName() + " : locked-> " + resource2);
lock1.unlock();
lock2.unlock();
};
Runnable run2 = new Runnable() {
@Override
public void run() {
lock2.lock();
lock1.lock();
System.out.println(Thread.currentThread().getName() + " : locked-> " + resource2);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println(Thread.currentThread().getName() + " : locked-> " + resource1);
lock2.unlock();
lock1.unlock();
}
};
Thread thread1 = new Thread(run1);
thread1.setName("Desktop");
Thread thread2 = new Thread(run2);
thread2.setName("Laptop");
thread1.start();
thread2.start();
}
}
我尝试颠倒锁的顺序..但代码有时执行得很好,有时会出现死锁,控制台中什么也没有。
请解释行为。
【问题讨论】:
-
在这两种情况下,死锁都可能发生或不发生。您无法控制线程的调度方式。如果死锁没有发生,并不意味着它不会发生。你应该以一种确保它永远不会发生的方式编写代码。
-
但是我尝试连续多次运行第一个代码,它总是导致死锁,而第二个没有。
标签: java multithreading deadlock synchronized reentrantlock