我最近访问了一些面试。面试官让我写保证死锁。
我写了以下内容:
public class DeadLockThreadSleep {
private static class MyThread implements Runnable {
private Object o1;
private Object o2;
@Override
public void run() {
try {
test(o1, o2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public MyThread(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
public void test(Object o1, Object o2) throws InterruptedException {
synchronized (o1) {
System.out.println("1.acquired: " + o1);
Thread.sleep(1000);
synchronized (o2) {
System.out.println("2.acquired: " + o2);
}
}
}
}
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
new Thread(new MyThread(o1, o2)).start();
new Thread(new MyThread(o2, o1)).start();
}
}
然后他问我是否确定它是有保证的。我记得 Thread.sleep 没有任何保证。
然后我写了这段代码:
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这个答案被接受了。
他还要求通过等待/通知编写模拟。想了很多,想不出怎么写。
这可能吗?
最佳答案
这可以通过创建一个循环来完成,其中一个线程持有一个资源并等待另一个资源,而另一个线程以相反的顺序执行相同的操作。
线程 t
持有 resourceOne
并等待 resourceTwo
,而 t1
持有 resourceTwo
并等待 resourceOne
下面是一个示例代码:
public class WaitNotifyLock {
boolean isONHold = false;
public synchronized void hold(){
while(isONHold){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isONHold = true;
System.out.println(Thread.currentThread().getId() + " : Holded");
}
public synchronized void unHold(){
while(!isONHold){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getId() + " : Produced");
isONHold = false;
notify();
}
public static void main(String[] args) {
WaitNotifyLock resourceOne = new WaitNotifyLock();
WaitNotifyLock resourceTwo = new WaitNotifyLock();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
resourceOne.hold();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resourceTwo.hold();
resourceOne.unHold();
resourceTwo.unHold();
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
resourceTwo.hold();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resourceOne.hold();
resourceTwo.unHold();
resourceOne.unHold();
}
});
t.start();
t1.start();
}
}
关于java - 如何通过等待/通知编写保证死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41440845/