java中的死锁

时间:2009-07-09 12:36:26

标签: java multithreading

任何人都可以发布最终陷入死锁的java代码吗?

7 个答案:

答案 0 :(得分:4)

答案 1 :(得分:2)

答案 2 :(得分:0)

创建两个锁,以及两个同步它们的线程,确保线程1先锁定1,反之亦然。在第一次锁定后,确保线程进入休眠状态一段时间。

public class DeadlockTest {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        new Thread("1") {
            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                    }
                    synchronized (lock2) {
                        System.out.println("1 got em");
                    }
                }
            }

        }.start();
        new Thread("2") {
            @Override
            public void run() {
                synchronized (lock2) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                    }
                    synchronized (lock1) {
                        System.out.println("2 got em");
                    }
                }
            }

        }.start();
    }
}

正如您将看到的那样,“得到它们”的印刷品都不会发生。

答案 3 :(得分:0)

这会导致死锁:

public static void main(String[] args) 
{
  final Object object1 = new Object();
  final Object object2 = new Object();

  Thread thread1 = new Thread(
    new Runnable() 
    {
      public void run() 
      {    
        try 
        {    
          //**** Lock on object1 first ****
          synchronized(object1) 
          {    
            Thread.sleep(1000);

            //**** Lock on object2 second ****
            synchronized(object2) 
            {
              System.out.println("Should never get here.");
            }
          }
        }
        catch (InterruptedException e) {}
      }
    }
  );

  Thread thread2 = new Thread(
    new Runnable() 
    {
      public void run() 
      {
        try 
        {
          //**** Lock on object2 first ****
          synchronized(object2) 
          {    
            Thread.sleep(1000);

            //**** Lock on object1 second ****
            synchronized(object1) 
            {
              System.out.println("Should never get here.");
            }
          }
        }
        catch (InterruptedException e) {}
      }
    }
  );

  thread1.start();
  thread2.start();
}

答案 4 :(得分:0)

将信号量初始化为0将始终导致死锁。 原因可以在enter方法的第一行看到:“while(value == 0){this.wait}”

class Semaphore {
    private int value;

    public Semaphore (int init){
        value = init;
    }

    synchronized public void exit() {
        if (value == 0) this.notify();
        ++value;
    }

    synchronized public void enter() throws InterruptedException {
        while (value == 0){
            this.wait();
        }
        --value;
    }
}

class myThread extends Thread{

    Semaphore mutex;

    public myThread(Semaphore s){
        mutex = s;
    }    

    public void run(){
        for(int x=0; x<10;<x++){
            mutex.enter();
            System.out.println(x);
            mutex.exit();
        }
    }
    public static void main(String [ ] args){
        Semaphore s = new Semaphore(0);
        Thread t1 = new myThread(s);
        Thread t2 = new myThread(s);

        t1.start();
        t2.start()
    }


}

答案 5 :(得分:0)

您还可以使用固定大小的线程池进行死锁:

final ExecutorService exec = Executors.newFixedThreadPool(1);
exec.submit(new Runnable() {
    public void run() {
       Future<?> f = exec.submit(new Runnable() {
           public void run() {
           }
       });
       try { f.get(); } catch (Exception ex) { }
    }
});

答案 6 :(得分:0)

正如其他答案所说,让两个线程以相反的顺序获得两个锁是导致死锁的一种方法(只要它们在请求第二个锁之前都持有第一个锁)。在下面的代码中,Thread1获得lockA,而线程2获得lockB。一旦他们都获得了第一个锁,他们就会尝试获取另一个线程的锁 - 但是它们会死锁(因为另一个线程仍然有锁)。

不是使用Thread.sleep()来等待第一次锁定,这可能会稍微不可预测并使测试更难/更慢,您可以使用CyclicBarrier来确保两个线程之前获得了第一次锁定他们试图获得他们的第二个(因为他们以相反的顺序获得对方的锁,我们将保证死锁):

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Deadlocker {
    private static class Worker implements Runnable {
        private Object firstLock;
        private CyclicBarrier firstLockHeld;
        private Object secondLock;
        public Worker(Object firstLock, CyclicBarrier firstLockHeld, Object secondLock) {
            this.firstLock = firstLock;
            this.firstLockHeld = firstLockHeld;
            this.secondLock = secondLock;
        }

        @Override
        public void run() {
            synchronized (firstLock) {
                try {
                    firstLockHeld.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();    // Will not happen unless another thread interrupts
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();    // Will not happen unless another thread interrupts
                }
                synchronized (secondLock) {
                    System.err.println("Should never happen!");
                }
            }
        }
    }

    public static void main(String[] args) {
        CyclicBarrier firstLockHeld = new CyclicBarrier(2);
        Object lockA = new Object();
        Object lockB = new Object();

        new Thread(new Worker(lockA, firstLockHeld, lockB)).start();
        new Thread(new Worker(lockB, firstLockHeld, lockA)).start();
    }
}