如何在Java中创建死锁
时间:2020-01-09 10:35:30 来源:igfitidea点击:
如果询问我们什么是Java死锁,那么几乎总是伴随着如何在Java中创建死锁的问题。
多线程中的死锁是一种情况,其中两个或者更多线程正在彼此等待释放资源以取得进一步的进展,并在此过程中永远被阻塞。
用于创建死锁的Java程序
当嵌套的同步块具有相反的对象顺序时,我们可能会在Java中陷入僵局。
在示例中,创建了两个线程来运行两个单独的可运行任务。在每个可运行的任务中,都有嵌套的同步块以相反的顺序获取对象锁,从而产生了死锁。
class ThreadA implements Runnable{
private Object obj1;
private Object obj2;
ThreadA(Object obj1, Object obj2){
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
synchronized(obj1){
System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
System.out.println(Thread.currentThread().getName() + " waiting for " + "obj2 lock");
synchronized(obj2){
System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
}
}
}
}
class ThreadB implements Runnable{
private Object obj1;
private Object obj2;
ThreadB(Object obj1, Object obj2){
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
synchronized(obj2){
System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
System.out.println(Thread.currentThread().getName() + " waiting for " + "obj1 lock");
synchronized(obj1){
System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
}
}
}
}
public class DLDemo {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
Thread t1 = new Thread(new ThreadA(obj1, obj2));
Thread t2 = new Thread(new ThreadB(obj1, obj2));
t1.start();
t2.start();
}
}
输出:
Thread-0 acquired obj1 lock Thread-0 waiting for obj2 lock Thread-1 acquired obj2 lock Thread-1 waiting for obj1 lock
我们可以在ThreadA的run()方法中看到,同步块获取obj1的锁,然后尝试获取obj2的锁。 ThreadB同步块的run()方法中的方法相同,它获取对obj2的锁定,然后尝试获取对obj1的锁定。当t1线程正在等待获取当前由t2线程获取的obj2上的锁,而t2线程正在等待获取当前由t1线程获取的obj1上的锁时,这会通过创建死锁来挂起程序。
通过从另一个调用一个同步方法来创建死锁
这是在Java中创建死锁的另一个示例。它与此处的第一个示例类似,而不是具有嵌套的同步块,而是有两种同步方法。用于调用该方法的对象和作为参数传递给这些方法的对象被颠倒,从而产生死锁。
public class DLDemo {
public synchronized void method1(DLDemo obj){
System.out.println(Thread.currentThread().getName() + " In Method1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Calling another synchronized method
obj.method2(this);
}
public synchronized void method2(DLDemo obj2){
System.out.println("In Method2");
}
public static void main(String[] args) {
DLDemo obj1 = new DLDemo();
DLDemo obj2 = new DLDemo();
new Thread(new Runnable() {
public void run() { obj1.method1(obj2); }
}).start();
//Thread 2
new Thread(new Runnable() {
public void run() { obj2.method1(obj1); }
}).start();
}
}
输出:
Thread-0 In Method1 Thread-1 In Method1
从一个线程使用obj1调用同步方法method1,因此该线程获取obj1的锁,然后使用obj2调用另一同步方法method2.
从另一个线程使用obj2调用同步方法method1,因此该线程获取obj2的锁,然后使用obj1调用另一个同步方法method2.

