线程死锁

一、产生死锁的原因

由于多个线程共同竞争同一个资源导致的一种僵局,若无外力作用,这些进程都将无法继续相向前推进。

eg:

public class DeadLock {
    /*  public static void a(){
          synchronized (String.class){
              System.out.println("String上的锁");
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              synchronized (Integer.class){
                  System.out.println("Integer上的锁");
              }

          }
      }
      public static void b(){
          synchronized (Integer.class){
              System.out.println("Integer上的锁");
              synchronized (String.class){
                  System.out.println("String上的锁");
              }

          }
      }

      public static void main(String[] args) {
          a();
          b();
      }*/
    public static void main(String[] args) {
        final Object a = new Object();
        final Object b = new Object();
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                synchronized (a) {
                    try {
                        System.out.println("now i in threadA-locka");
                        Thread.sleep(1000l);
                        synchronized (b) {
                            System.out.println("now i in threadA-lockb");
                        }
                    } catch (Exception e) {
                        // ignore
                    }
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            public void run() {
                synchronized (b) {
                    try {
                        System.out.println("now i in threadB-lockb");
                        Thread.sleep(1000l);
                        synchronized (a) {
                            System.out.println("now i in threadB-locka");
                        }
                    } catch (Exception e) {
                        // ignore
                    }
                }
            }
        });

        threadA.start();
        threadB.start();
    }
}

二、死锁产生的条件

1.互斥条件:进程对所分配的资源进行排他性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求进程只能等待,直至占有该资源的进程用毕释放;

2.请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己获得资源保持不放;

3.不可抢占条件:进程以获得的资源在未使用完之前不能被抢占,只能在自己使用完后由自己释放;

4.循环等待条件:发生死锁时,必然存在一个(进程--资源)循环链,即进程集合{p0 ,p1 ,p2 ,…,pn}中的p0等待正在等待一个p1占用的资源,p1正在等待p2占用的资源.....

三、检测死锁的方式

1.Jstack工具:java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。

2.JConsole工具:JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。

四、如何预防死锁

1.按确定的顺序访问锁

public class DeadLock {
    /*  public static void a(){
          synchronized (String.class){
              System.out.println("String上的锁");
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              synchronized (Integer.class){
                  System.out.println("Integer上的锁");
              }

          }
      }
      public static void b(){
          synchronized (Integer.class){
              System.out.println("Integer上的锁");
              synchronized (String.class){
                  System.out.println("String上的锁");
              }

          }
      }

      public static void main(String[] args) {
          a();
          b();
      }*/
    public static void main(String[] args) {
        final Object a = new Object();
        final Object b = new Object();
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                synchronized (a) {
                    try {
                        System.out.println("now i in threadA-locka");
                        Thread.sleep(1000l);
                        synchronized (b) {
                            System.out.println("now i in threadA-lockb");
                        }
                    } catch (Exception e) {
                        // ignore
                    }
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            public void run() {
                synchronized (a) {
                    try {
                        System.out.println("now i in threadB-lockb");
                        Thread.sleep(1000l);
                        synchronized (b) {
                            System.out.println("now i in threadB-locka");
                        }
                    } catch (Exception e) {
                        // ignore
                    }
                }
            }
        });

        threadA.start();
        threadB.start();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值