精华内容
下载资源
问答
  • java多线程死锁解决方法解决方法:http://www.yayihouse.com/yayishuwu/chapter/1302

    java多线程死锁解决方法

    解决方法http://www.yayihouse.com/yayishuwu/chapter/1302

    展开全文
  • 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。java 死锁产生的四个必要条件:1、互斥使用,即当资源被一个线程使用...

    更多面试题请狠狠的点击 下载


    死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。java 死锁产生的四个必要条件:1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

    package com.suo;
    //父亲
    public class Father {
    	public void say(){
    		System.out.println("对孩子说,给我成绩单,我就把玩具给你");
    	}
    	public void get(){
    		System.out.println("爸爸得到成绩单");
    	}
    }


    儿子类

    pack
    展开全文
  • 经常看以前大学里面的教材中的一个解决线程死锁的例子,其技术叫做"资源排序",但代码只是一部分,我今天把它写全,这里的关键点是线程对各个对象加锁顺序一定得保持一致.   /** * 此类轻易的解决了...

          经常看以前大学里面的教材中的一个解决线程死锁的例子,其技术叫做"资源排序",但代码只是一部分,我今天把它写全,这里的关键点是线程对各个对象加锁顺序一定得保持一致.

     

    /**
     * 此类轻易的解决了死锁问题,其核心思想为 各线程按照顺序依次对各对象加锁,
     * 假设有三个线程需要竞争三个资源,线程加锁顺序是 lock1,lock2,lock3,这个应该称作为 "资源排序"
     * 
     * @author Chase
     *
     */
    public class DeadLockSolution {
    	private static final Object lock1 = new Object();
    
    	private static final Object lock2 = new Object();
    	
    	private static final Object lock3 = new Object();
    
    	private Thread1 thread1 = new Thread1();
    
    	private Thread2 thread2 = new Thread2();
    	
    	private Thread3 thread3 = new Thread3();
    
    	class Thread1 extends Thread {
    		public void run() {
    			synchronized (lock1) {
    				
    				System.out.println("线程1已对 1资源 加锁");
    				
    				try {
    					
    					Thread.sleep(1000);
    					
    				} catch (InterruptedException e) {}
    				
    				
    				synchronized (lock2) {
    					
    					System.out.println("线程1已对 2资源 加锁");
    					
    					try {
    						
    						Thread.sleep(1000);
    						
    					} catch (InterruptedException e) {}
    					
    					synchronized (lock3) {
    						
    						System.out.println("线程1已对 3资源 加锁");
    						
    						try {
    							
    							Thread.sleep(1000);
    							
    						} catch (InterruptedException e) {}
    					}
    				}
    			}
    			System.out.println("线程1运行完毕!");
    		}
    	}
    
    	class Thread2 extends Thread {
    		public void run() {
    			
    			synchronized (lock1) {
    				
    				System.out.println("线程2已对 1资源 加锁");
    				
    				try {
    					
    					Thread.sleep(1000);
    					
    				} catch (InterruptedException e) {}
    				
    				synchronized (lock2) {
    					
    					System.out.println("线程2已对 2资源 加锁");
    					
    					try {
    						
    						Thread.sleep(1000);
    						
    					} catch (InterruptedException e) {}
    					
    					synchronized (lock3) {
    						
    						System.out.println("线程2已对 3资源 加锁");
    						
    						try {
    							
    							Thread.sleep(1000);
    							
    						} catch (InterruptedException e) {}
    					}
    				}
    			}
    			System.out.println("线程2运行完毕!");
    		}
    	}
    	
    	class Thread3 extends Thread {
    		public void run() {
    			
    			synchronized (lock1) {
    				
    				System.out.println("线程3已对 1资源 加锁");
    				
    				try {
    					
    					Thread.sleep(1000);
    					
    				} catch (InterruptedException e) {}
    				
    				synchronized (lock2) {
    					
    					System.out.println("线程3已对 2资源 加锁");
    					
    					try {
    						
    						Thread.sleep(1000);
    						
    					} catch (InterruptedException e) {}
    					
    					synchronized (lock3) {
    						
    						System.out.println("线程3已对 3资源 加锁");
    						
    						try {
    							
    							Thread.sleep(1000);
    							
    						} catch (InterruptedException e) {}
    					}
    				}
    			}
    			System.out.println("线程3运行完毕!");
    		}
    	}
    
    	public DeadLockSolution() {
    		thread1.start();
    		thread2.start();
    		thread3.start();
    	}
    
    	public static void main(String[] args) {
    		new DeadLockSolution();
    	}
    }

     

    运行结果:

     

    线程1已对 1资源 加锁
    线程1已对 2资源 加锁
    线程1已对 3资源 加锁
    线程1运行完毕!
    线程3已对 1资源 加锁
    线程3已对 2资源 加锁
    线程3已对 3资源 加锁
    线程2已对 1资源 加锁
    线程3运行完毕!
    线程2已对 2资源 加锁
    线程2已对 3资源 加锁
    线程2运行完毕! 

     

    不同的机器线程运行的先后可能不太一样,但是应该不会出现死锁的情况.

    展开全文
  • 解决线程死锁的办法是什么? 如何避免死锁? 什么是线程死锁? 首先是一个线程需要多把锁,并发的时候多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能...

    面试题

    1. 什么是线程死锁,?
    2. 产生死锁的四个必要条件?
    3. 解决线程死锁的办法是什么?
    4. 如何避免死锁?

    什么是线程死锁?

    首先是一个线程需要多把锁,并发的时候多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

    如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。

    下面通过一个例子来说明线程死锁,代码模拟了上图的死锁的情况 (代码来源于《并发编程之美》):

    public class DeadLockDemo {
        private static Object resource1 = new Object();//资源 1
        private static Object resource2 = new Object();//资源 2
    
        public static void main(String[] args) {
            new Thread(() -> {
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource2");
                    synchronized (resource2) {
                        System.out.println(Thread.currentThread() + "get resource2");
                    }
                }
            }, "线程 1").start();
    
            new Thread(() -> {
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource1");
                    synchronized (resource1) {
                        System.out.println(Thread.currentThread() + "get resource1");
                    }
                }
            }, "线程 2").start();
        }
    }
    

    Output

    Thread[线程 1,5,main]get resource1
    Thread[线程 2,5,main]get resource2
    Thread[线程 1,5,main]waiting get resource2
    Thread[线程 2,5,main]waiting get resource1
    
    1. 线程 A 通过 synchronized (resource1)获得resource1 的监视器锁
    2. 通过Thread.sleep(1000);让线程A休眠1s为的是让线程B得到执行然后获取到resource2的监视器锁。
    3. 线程 A 和线程B休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。

    产生死锁的四个必要条件?

    • 互斥条件:该资源任意一个时刻只由一个线程占用。
    • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    • 不剥夺条件:线程已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
    • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    如何避免死锁?

    • 破坏互斥条件: 这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。
    • 破坏请求与保持条件:
      一次性申请所有的资源。
    • 破坏不剥夺条件:
      占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
    • 破坏循环等待条件: 靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。

    我们只要破坏产生死锁的四个条件中的其中一个就可以了,一般情况下解决线程死锁通常的解决办法是先对锁申请进行排序。

    我们对线程 2 的代码修改成下面这样就不会产生死锁了

    new Thread(() -> {
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "waiting get resource2");
                    synchronized (resource2) {
                        System.out.println(Thread.currentThread() + "get resource2");
                    }
                }
            }, "线程 2").start();
    

    Output

    Thread[线程 1,5,main]get resource1
    Thread[线程 1,5,main]waiting get resource2
    Thread[线程 1,5,main]get resource2
    Thread[线程 2,5,main]get resource1
    Thread[线程 2,5,main]waiting get resource2
    Thread[线程 2,5,main]get resource2
    
    Process finished with exit code 0
    

    我们分析一下上面的代码为什么避免了死锁的发生?

    线程 1 首先获得到 resource1 的监视器锁,这时候线程 2 就获取不到了。然后线程 1 再去获取 resource2 的监视器锁,可以获取到。然后线程 1 释放了对 resource1、resource2 的监视器锁的占用,线程 2 获取到就可以执行了。这样就破坏了破坏循环等待条件,因此避免了死锁。

    再举一个工作中死锁的例子(丁威老师的案例)

    import java.util.List;
    public class LockTest {
        
        // 例如这个方法上有一个事务注解
        public void updateBusiness(List<Long> goodsIds) {
    
            if(goodsIds == null || goodsIds.isEmpty()) {
                return;
            }
            IGoodsDao goodsDao = null;
    
            for(Long gid : goodsIds) {
                goodsDao.updateGoods(gid, 1);  // 将库存减去1,需要持有该记录的行锁
            }
        }
    }
    
    interface  IGoodsDao {
        // 减库存
        void updateGoods(Long goodsId, int nums);
    }
    
    1. 如果一个用户要购买商品ID 为 1,3 的商品
    2. 而另外一个用户需要购买同样的商品,但是在购物车中选择商品的顺序是 3,1
    3. 此时两个线程同时调用 updateBusiness 方法

    执行轨迹如下:

    这样就出现了死锁。

    避免死锁的方法:
    1. 数据库锁的加锁和解锁需要在同一个数据库连接里,否则会出现解锁失败
    2. 避免一个线程获取多个锁
    3. 尝试使用定时锁,lock.tryLock(timeOut)替换内部锁
    4. 避免一个锁内同时占用多个资源,尽量保证每一个锁内只占用一个资源

    针对上面的例子,通常的解决办法是,先对锁申请进行排序。

    // 例如这个方法上有一个事务注解
        public void updateBusiness(List<Long> goodsIds) {
    
            if(goodsIds == null || goodsIds.isEmpty()) {
                return;
            }
            IGoodsDao goodsDao = null;
    
            Collections.sort(goodsIds);
    
            for(Long gid : goodsIds) {
                goodsDao.updateGoods(gid, 1);  // 将库存减去1,需要持有该记录的行锁
            }
        }
    

    这样就不会出现死锁了。

    如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。 感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。

    原创不易,欢迎转发,关注公众号“码农进阶之路”,获取更多面试题,源码解读资料!
    在这里插入图片描述

    展开全文
  • 线程死锁以及死锁解决的方法 目录 线程死锁以及死锁解决的方法 一、什么是死锁 二、死锁产生的条件 三、代码演示 1. 死锁产生 2.调整加锁顺序避免死锁产生 3. 加锁时限避免死锁产生 一、什么是死锁 死锁是...
  • 点击上方“码农进阶之路”,选择“设为星标”回复“面经”获取面试资料面试题什么是线程死锁,?产生死锁的四个必要条件?解决线程死锁的办法是什么?如何避免死锁?什么是线程死锁?首先是一个线程需...
  • 主要介绍了Java线程死锁实例及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 解决线程死锁

    2015-03-26 17:49:49
    和人们所说的一样,线程死锁解决方式就是破坏线程死锁的的产生条件,上一篇文章说到 1 互斥条件 线程使用的资源必须至少有一个是不能共享的 2 请求与保持条件 至少有一个线程必须持有一个资源并且正在等待获取...
  • 主要介绍了 Java 线程死锁的问题解决办法的相关资料,希望通过本大家能帮助到大家,遇到类似问题能够解决,需要的朋友可以参考下
  • 主要介绍了python 多线程死锁问题的解决方案,帮助大家更好的理解和学习python 锁,感兴趣的朋友可以了解下
  • 主要介绍了JVM---jstack分析Java线程CPU占用,线程死锁解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • Java线程死锁解决方案

    千次阅读 2016-09-24 00:13:57
    要了解线程死锁,首先要明白什么是死锁 死锁 通俗点讲:死锁就是两个或两个以上的进程或线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。 ...
  • 线程死锁及其解决

    千次阅读 2017-06-03 11:05:01
    一、什么是死锁 死锁:(摘自百度百科) 两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远...
  • 线程死锁解决办法

    千次阅读 2020-02-05 12:34:27
    所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。 死锁产生的必要条件 以下这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述...
  • Java线程死锁需要如何解决

    千次阅读 2016-12-07 17:59:10
    Java线程死锁如何避免这一悲剧 Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键。不幸的是,使用上锁会带来其他问题。让我们来看一些常见问题以及相应的解决方法:  Java线程死锁 ...
  • 线程死锁以及解决方法

    千次阅读 2017-06-09 23:11:44
    解决死锁没有简单的方法,这是因为线程产生死锁都各有各的原因,而且往往具有很高的负载。大多数软件测试产生不了足够多的负载,所以不可能暴露所有的线程错误。在这里中,下面将讨论开发过程常见的4类典型的死锁和...
  • 线程死锁

    2016-05-05 12:26:04
    线程死锁是多线程中最头疼的问题,一旦进入线程死锁,很多时候只能通过外部进程重启才能解决问题 线程到达死锁的四个条件: 互斥条件:一个资源每次只能被一个线程使用 资源独占条件:一个线程因请求资源而阻塞时...
  • 如果我们在程序中遇到线程死锁的时候,该怎么去解决呢? 本文将会从一个实际的例子出发,一步一步的揭开java问题解决的面纱。 死锁的代码 写过java多线程程序的人应该都知道,多线程中一个很重要的事情就是状态的...
  • python多线程死锁解决方案

    千次阅读 2019-04-12 20:25:18
    python3 一 多线程死锁问题及解决方案 死锁:前提是有多个锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于...
  • 实测有效的一个c++检测线程死锁解决方法(实现和测试代码) 原创实测有效的一个c++检测线程死锁解决方法,已应用于项目,实测有效 原创文章地址:https://blog.csdn.net/liaozhilong88/article/details/80354414...
  • JAVA 多线程死锁问题及解决

    千次阅读 2013-03-11 00:11:42
    Java线程死锁如何避免这一悲剧 Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键。不幸的是,使用上锁会带来其他问题。让我们来看一些常见问题以及相应的解决方法:  Java线程死锁...
  • 为了解决线程死锁问题,不是不使用锁,而是用信号量去控制。 信号量可以控制资源能被多少线程访问,此处指定只能被一个线程访问,就实现了锁的功能;然而,信号量可以指定获取的超时时间,所以,可以根据这个超时...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 125,782
精华内容 50,312
关键字:

线程死锁如何解决