如何在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.