精华内容
下载资源
问答
  • 死锁:指两个或两个以上的线程在执行过程中,由于竞争资源或者...死锁原因:两个及两个以上的线程,抢占2把及两把以上的锁,抢占锁的顺序不一致 发现线程死锁的方法: public class DeadLockSample { private fin...

    死锁:指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力的作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程称为死锁线程

    在这里插入图片描述

    死锁原因:两个及两个以上的线程,抢占2把及两把以上的锁,抢占锁的顺序不一致

    发现线程死锁的方法:

    public class DeadLockSample {
        private final static Object lock1 = new Object();
        private final static String lock2 = new String();
    
    
        public static void main(String[] args) throws Exception {
            newThread("ThreadA", lock1, lock2).start();
    
            newThread("ThreadB", lock2, lock1).start();
    
            System.in.read();
        }
    
        private static Thread newThread(String threadName, Object lockFirst, Object lockSecond) {
            return new Thread(() -> {
                synchronized (lockFirst) {
                    System.out.println(Thread.currentThread().getName() + " holding lockFirst");
                    try {
                        Thread.sleep(3000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " waiting lockSecond");
                    synchronized (lockSecond) {
                        System.out.println(Thread.currentThread().getName() + " holding lockSecond");
                    }
                }
            }, threadName);
        }
    }
    

    结果:
    在这里插入图片描述

    解决方法:使用jps命令和jstack命令

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    如何避免代码出现的线程死锁:

    1.尽量不要使用2把及以上的锁
    2.必须使用2把及以上锁的时候,确保在整个应用程序中对获取锁的顺序是一致的
    3.尝试获取具有超时释放的锁,例如Lock中的tryLock来获取锁
    4.当发生了Java-level的锁时,分析原因,修改代码,然后重启程序来干掉进程/线程
    展开全文
  • 死锁原因线程死锁的本质在于不同线程对资源锁的竞争,如果竞争中存在闭环,则会出现死锁。而为了避免死锁,最关键的是避免出现资源锁竞争的闭环。 避免死锁的秘诀:资源按顺序调用。 理解:1、资源指的是需要加锁...

    死锁原因

            线程死锁的本质在于不同线程对资源锁的竞争,如果竞争中存在闭环,则会出现死锁。而为了避免死锁,最关键的是避免出现资源锁竞争的闭环。

    避免死锁的秘诀

            资源按顺序调用。

    理解

            1、资源指的是需要加锁的对象,不加锁就不存在竞争,也就谈不上资源的死锁。2、不同线程在调用资源时,均需按相同的顺序调用资源。

    示例

           以下的示例只要testSynchronized方法传入的资源顺序相同,即不可能出现死锁,顺序不同则会死锁。

    public class MainTest {
        public static void main(String[] args) {
            MainTest mainTest = new MainTest();
    
            String[] a = new String[4];
            String[] b = new String[4];
    
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    mainTest.testSychronized(a, b);
                }
            });
            thread.setName("T-A");
            thread.start();
    
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    mainTest.testSychronized(b, a);
                }
            });
            thread2.setName("T-B");
            thread2.start();
        }
    
        private void testSychronized(String[] a, String[] b) {
            for (int i = 0; i < 1000; i++) {
                synchronized (a) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (b) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                System.out.println(Thread.currentThread().getName());
            }
        }
    }


    展开全文
  • 线程死锁原因和避免方法

    千次阅读 2019-04-23 17:40:00
    在申请锁时发生了交叉闭环,即线程在获得了锁A并且没有释放的情况下去申请锁B,这时,另一个线程已经获得了锁B,在释放锁B之前又要先获得锁A,因此闭环发生,陷入死锁循环。 引用:...

    死锁定义

           在申请锁时发生了交叉闭环,即线程在获得了锁A并且没有释放的情况下去申请锁B,这时,另一个线程已经获得了锁B,在释放锁B之前又要先获得锁A,因此闭环发生,陷入死锁循环。

    引用:https://blog.csdn.net/lyabc123456/article/details/81060477

    死锁例子代码(引用)

    public class DeadLockA extends Thread {
        @Override
        public void run() {
            try{
                 while(true){
                    //LockA申请锁obj1
                    synchronized(TestLockAB.obj1){
                        System.out.println("LockA locked obj1");
    
                        //LockA睡眠1秒,让LockB有时间锁住obj2
                        Thread.sleep(1000);
                        System.out.println("LockA trying to lock obj2...");
    
                       //LockA在没有释放obj1的情况下去申请锁obj2
                        synchronized(TestLockAB.obj2){
                            //LockA locked obj2 执行不到
                            System.out.println("LockA locked obj2");
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    public class DeadLockB extends Thread {
        @Override
        public void run() {
            try{
                while(true){
                    //LockB申请锁obj2
                    synchronized(TestLockAB.obj2){
                        System.out.println("LockB locked obj2");
                        System.out.println("LockB trying to lock obj1...");
    
                        //LockB在没有释放obj2时申请锁住obj1
                        synchronized(TestLockAB.obj1){
                            //LockB locked obj1 执行不到
                            System.out.println("LockB locked obj1");
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    public class TestLockAB {
        public static final String obj1 = "obj1";
        public static final String obj2 = "obj2";
    
        public static void main(String[] ars) {
            new DeadLockA().start();
            new DeadLockB().start();
        }
    }
    
    
    输出结果:
    LockA locked obj1
    LockB locked obj2
    LockB trying to lock obj1...
    LockA trying to lock obj2...

    死锁原因:
    (1) 因为系统资源不足。
    (2) 进程运行推进的顺序不合适。
    (3) 资源分配不当等。

    产生死锁的四个必要条件:
    (1) 互斥条件:一个资源每次只能被一个进程使用。
    (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
    (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
    这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

     

    避免死锁的方法:

    1.加锁顺序:当多个线程要相同的一些锁,但是按照不同的顺序加锁,死锁的情况发生率较高,如果,程序运行能确保所有线程都是按照相同的顺序去获得锁,那么死锁就不会发生。

     2.加锁时限:加一个超时时间,若一个线程没有在给定的时间内成功获取所需的锁,则进行回退操作,并释放自己本身所持有的锁,一段随机时间之后,重新去获取锁。

    3.死锁检测:死锁检测,每当线程去获取锁的时候,会在线程和锁相关的数据结构中将其记下,除此之外,每当线程请求锁,都需要记录在数据结构中。死锁检测是一个死锁避免机制。他主要针对的时那些不可能实现按序加锁并且锁超时也不可行的应用场景。

     

    具体引用:https://blog.csdn.net/coslay/article/details/45593859

     

    展开全文
  • 多线程专题之线程死锁原因之谜

    千次阅读 2013-08-09 10:54:02
    引子:线程死锁曾是多少程序员的噩梦,每每为此食不甘味,夜不成寐,一句话:苦不堪言。本文从几个场景入手,试图解开产生死锁的原因之谜。 教科书:说的很具体,理解很抽象  关于死锁产生的原因《操作系统》中有...

    引子:线程死锁曾是多少程序员的噩梦,每每为此食不甘味,夜不成寐,一句话:苦不堪言。本文从几个场景入手,试图解开产生死锁的原因之谜。

    教科书:说的很具体,理解很抽象

      关于死锁产生的原因《操作系统》中有比较好的说明:

      (1)因为系统资源不足。

      (2)进程运行推进的顺序不合适。

      (3)资源分配不当等。

      关于死锁出现的必要条件也有比较具体的说明:

      (1)互斥条件:一个资源每次只能被一个进程使用。

      (2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

      (3)不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

      (4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

      这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,这也为我们实际应用中定位死锁问题,提供了路由。

    情景一、不加锁,两线程访问,变量访问示例

      关于死锁,有锁才能死,如果我们不加锁,自然不会发生死锁,但是如果不加锁,对资源的访问,将会发生什么情况呢。不妨看下面的例子:

      当两个线程读写相同变量时,线程A读取变量然后给予变量赋予一个新的值,但是写操作需要两个存储器周期。当线程B在这两个存储器周期中间读取这个相同变量时,它就会得到不一致的值。这就是为什么要对多线程资源访问进行加锁,加锁以后的访问顺序就变成了顺序访问,从而可以避免资源的不一致访问。

    情景二、不加锁,多线程访问,增量操作示例

      当两个或多个线程试图在同一时间修改同一个变量时,如果不加锁也会出现数据资源不一致的情况。如下图所示:

      我们可以看到,增量操作分为三个步骤进行:(1)从内存单元读入寄存器。(2)从寄存器中进行变量值的增加。(3)把新的值写回内存单元。如果两个线程试图同时对统一变量执行增量操作时,结果可能出现不一致。变量可能比原来增加了1,也可能增加了2,具体是1,还是2取决于第二个线程读取变量时获得的值是5还是6。这里面有一个前提就是变量增加的操作不是原子操作,这是因为现代计算机系统中,存储器访问需要多个总线周期,多处理器的总线周期通常在多个处理器上是交叉的,所以无法保证数据时顺序一致的。

    情景三、互斥锁,多变量部分锁

      以上示例已经讲明了我们为何需要线程锁,不加锁将会导致数据资源访问的不一致。可是加锁后,如果存在满足死锁的必要条件,又会产生死锁,我们该怎么办呢?不妨先来看一个示例:

    复制代码
      1 #include <stdlib.h>
      2 #include <pthread.h>
      3 
      4 #define NHASH 29
      5 #define HASH(fp) (((unsigned long)fp)%NHASH)
      6 
      7 struct foo *fh[NHASH];
      8 
      9 pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
     10 
     11 struct foo {
     12     int             f_count;
     13     pthread_mutex_t f_lock;
     14     struct foo     *f_next; /* protected by hashlock */
     15     int             f_id;
     16     /* ... more stuff here ... */
     17 };
     18 
     19 struct foo *
     20 foo_alloc(void) /* allocate the object */
     21 {
     22     struct foo    *fp;
     23     int            idx;
     24 
     25     if ((fp = malloc(sizeof(struct foo))) != NULL) {
     26         fp->f_count = 1;
     27         if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
     28             free(fp);
     29             return(NULL);
     30         }
     31         idx = HASH(fp);
     32         pthread_mutex_lock(&hashlock);
     33         fp->f_next = fh[idx];
     34         fh[idx] = fp->f_next;
     35         pthread_mutex_lock(&fp->f_lock);
     36         pthread_mutex_unlock(&hashlock);
     37         /* ... continue initialization ... */
     38         pthread_mutex_unlock(&fp->f_lock);
     39     }
     40     return(fp);
     41 }
     42 //增加
     43 void
     44 foo_hold(struct foo *fp) /* add a reference to the object */
     45 {
     46     pthread_mutex_lock(&fp->f_lock);
     47     fp->f_count++;
     48     pthread_mutex_unlock(&fp->f_lock);
     49 }
     50 //查找已经对象
     51 struct foo *
     52 foo_find(int id) /* find an existing object */
     53 {
     54     struct foo    *fp;
     55     int            idx;
     56 
     57     idx = HASH(fp);
     58     pthread_mutex_lock(&hashlock);
     59     for (fp = fh[idx]; fp != NULL; fp = fp->f_next) {
     60         if (fp->f_id == id) {
     61             foo_hold(fp);
     62             break;
     63         }
     64     }
     65     pthread_mutex_unlock(&hashlock);
     66     return(fp);
     67 }
     68 //减小
     69 void
     70 foo_rele(struct foo *fp) /* release a reference to the object */
     71 {
     72     struct foo    *tfp;
     73     int            idx;
     74 
     75     pthread_mutex_lock(&fp->f_lock);
     76     if (fp->f_count == 1) { /* last reference */
     77         pthread_mutex_unlock(&fp->f_lock);  //如果不解锁会怎么样呢?
     78         pthread_mutex_lock(&hashlock);    //如果顺序发生变化呢?
     79         pthread_mutex_lock(&fp->f_lock);
     80         /* need to recheck the condition */
     81         if (fp->f_count != 1) {
     82             fp->f_count--;
     83             pthread_mutex_unlock(&fp->f_lock);
     84             pthread_mutex_unlock(&hashlock);
     85             return;
     86         }
     87         /* remove from list */
     88         idx = HASH(fp);
     89         tfp = fh[idx];
     90         if (tfp == fp) {
     91             fh[idx] = fp->f_next;
     92         } else {
     93             while (tfp->f_next != fp)
     94                 tfp = tfp->f_next;
     95             tfp->f_next = fp->f_next;
     96         }
     97         pthread_mutex_unlock(&hashlock);
     98         pthread_mutex_unlock(&fp->f_lock);
     99         pthread_mutex_destroy(&fp->f_lock);
    100         free(fp);
    101     } else {
    102         fp->f_count--;
    103         pthread_mutex_unlock(&fp->f_lock);
    104     }
    105 }
    复制代码

    以上代码注意加锁的顺序,如果顺序错了,则会有可能出现死锁。

    展开全文
  • Java线程死锁如何避免这一悲剧 Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键。不幸的是,使用上锁会带来其他问题。让我们来看一些常见问题以及相应的解决方法:  Java线程死锁 ...
  • 那么线程一在执行过程中,e为A节点,next为B节点,此时线程暂停 线程二同样刚开始e为A节点,next为B节点 执行第一次while循环 e.next = newTable[i]; // A的next赋值为null(原来为B) newTable[i] = e; // 该下标赋值...
  • 一、导致线程死锁原因 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,而该资源又被其他线程锁定,从而导致每一个线程都得等其它线程释放其锁定的资源,造成了所有线程都无法正常结束。这是从...
  • 线程死锁的原因是多个线程同时被阻塞,它们中的一个或全部都在等待某个资源被释放,而该资源又被其他线程锁定。 产生死锁的四个必要条件: 互斥 不可抢占 请求保持 循环等待 死锁原因: 资源不够 进程推进顺序...
  • 线程死锁

    万次阅读 多人点赞 2019-09-03 23:12:56
    线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,在该线程释放这个锁之前,其它线程是获取不到这个锁的,而且会一直死等下去,因此这...
  • 多线程编程:线程死锁原因以及解决方法 关于线程死锁这个问题相信程序员在编写多线程程序时会经常遇到的一个经典问题,这种情况往往出现在多个线程同时对临界资源访问时所产生的。 属于临界资源的硬件有打印机、...
  • Java多线程死锁示例

    2020-08-27 00:23:39
    主要介绍了Java多线程死锁,结合实例形式分析了Java多线程出现死锁的相关原因与操作注意事项,需要的朋友可以参考下
  • Java线程死锁

    2016-09-16 21:47:33
    * 【线程死锁】 * 原因:两个线程相互等待被对方锁定的资源 */代码模拟:public class DeadLock { public static void main(String[] args) { Object obj = new Object(); Object obj1 = new Object(); ...
  • 线程死锁原因和解决办法

    千次阅读 2017-07-16 17:11:08
    前言 死锁问题是多线程特有的问题,它可以被认为是线程间切换...1. 线程死锁原因 (1)互斥条件:一个资源每次只能被一个线程使用。 (2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
  • 线程死锁造成的后果:所有的线程都被阻塞,并且线程的阻塞是无法解开的(因为可以解锁的线程也阻塞了)。 造成死锁的场景主要有如下几种: 加锁之后忘记解锁 重复加锁,造成死锁 程序中有多个共享资源,因此有很...
  • 产生死锁原因 竞争资源。当系统中供多个进程共享的资源如打印机、公用队列等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁。 进程间推进顺序非法。进程在运行过程中,请求和释放资源的...
  • 线程死锁 CPU过高 WeakHashMap 请求原因分析
  • 线程死锁

    2017-06-13 15:46:07
    1、【多线程死锁是怎么产生的呢??】 2、【死锁产生的4个必要条件】 3、【死锁产生的原因】 4、【产生死锁的几种场景】 5、【死锁避免的策略】

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 91,708
精华内容 36,683
关键字:

线程死锁原因