Java 为什么死锁在我的代码中断断续续地发生?

Java 为什么死锁在我的代码中断断续续地发生?,java,multithreading,Java,Multithreading,下面是我为死锁编写的代码,但对于小的“for-loop”,代码并没有陷入死锁,而当我将“for-loop”保持到10时,死锁就发生了 有人能解释一下,为什么它会表现出这样的行为吗 public class CustomerUpdateDeadloackThread { public static void main(String[] args) { Customer cstmr = new Customer("Peter"); Address adrs

下面是我为死锁编写的代码,但对于小的“for-loop”,代码并没有陷入死锁,而当我将“for-loop”保持到10时,死锁就发生了

有人能解释一下,为什么它会表现出这样的行为吗

public class CustomerUpdateDeadloackThread {

    public static void main(String[] args) {

        Customer cstmr = new Customer("Peter");
        Address adrs = new Address("B-232, Bangalore");


    // For loop till 3 is not showing deadlock.
    for (int i=0; i<10;i++){
        new Thread(new TagObjectsToEachOther(cstmr, adrs)).start();
        new Thread(new TagObjectsToEachOther(adrs, cstmr)).start();
    }


    }
}

interface CustomerUpdater {

    public boolean update(Object obj);

}

class TagObjectsToEachOther implements Runnable {
    CustomerUpdater taskItem;
    Object objToUpdateWith;

    public TagObjectsToEachOther(CustomerUpdater cspdtr, Object obj2) {
        this.taskItem = cspdtr;
        this.objToUpdateWith = obj2;
    }

    @Override
    public void run() {
        taskItem.update(objToUpdateWith);
        System.out.println(" Task done :" + Thread.currentThread().getName());
    }

}

class Address implements CustomerUpdater {

    String address;
    Customer customer;

    public Address(String addrs) {
        this.address = addrs;
    }

    @Override
     public boolean update(Object cstmr) {
        synchronized (this) {
            synchronized ((Customer) cstmr) {
                try {
                    this.customer = (Customer) cstmr;
                    Thread.sleep(2000); // or else do some other work here
                } catch (CustomerUpdateFailureException e) {
                    e.getCause();
                    return false;
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return true;
            }
        }
    }

}

class Customer implements CustomerUpdater {

    String name;
    Address address;

    public Customer(String nm) {
        this.name = nm;
    }

    @Override
     public boolean update(Object adrs) {
        synchronized (this) {
            synchronized ((Address) adrs) {
                try {
                    this.address = (Address) adrs;
                    Thread.sleep(2000); // or else do some other work here
                } catch (CustomerUpdateFailureException e) {
                    e.getCause();
                    return false;
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return true;
            }
        }
    }

}

class CustomerUpdateFailureException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    @Override
    public String getMessage() {

        return "Uncompitable update";
    }

}
公共类CustomerUpdateDeadloackThread{
公共静态void main(字符串[]args){
客户cstmr=新客户(“彼得”);
地址adrs=新地址(“班加罗尔B-232”);
//For循环直到3才显示死锁。

对于(int i=0;i只有当一个线程在第一个线程获得第二个监视器之前获得一个监视器,而另一个线程在第一个线程获得第二个监视器时,才会出现死锁。在这两个对象上获得监视器的线程越多,其中一个线程只获得一个锁的可能性就越大,并且在此之前被抢占它有机会获得第二个监视器

换句话说,这很好,只会导致等待:

  Thread A               Thread B
  Lock X
  Lock Y
                         Lock Y // Blocks (temporary)
  Sleep
                         Lock X
                         Sleep
鉴于这会导致死锁:

  Thread A               Thread B
  Lock X
                         Lock Y
  Lock Y // Blocks (deadlock)
                         Lock X // Blocks (deadlock)

如果将
线程.sleep(2000)
调用移动到两个
同步的
语句之间(在两种方法中)然后你几乎可以保证会出现死锁,在顶层没有任何循环。

你有一个基本上设计为死锁的程序。你可以更简单地说为什么不应该出现死锁。@Peter Lawrey:实际上我想要一个死锁代码。谢谢Jon Skeet。实际上,没有睡眠的死锁是间歇性的。@Rohan:是的添加睡眠只会使危险的代码段(线程只拥有一个监视器)花费更长的时间,从而“鼓励”死锁。