zoukankan      html  css  js  c++  java
  • 死锁手写及定位分析

    1、什么是死锁?

     死锁是指两个或者两个以上的进程在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉,那它们就无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很底,否则就会因为争夺有限资源而陷入死锁。

    2、死锁模型图

    image

    3、死锁产生的四个条件:


     互斥:共享资源X和Y只能被一个线程占用 
     占有且等待:线程T1已经获取共享资源X,在等待共享资源Y的时候,不释放共享资源X 
     不可抢占:其他线程不能强行抢占线程T1占有的资源 
     循环等待:线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,这就是循环等待。

    4、死锁手写编码 - 两个sync锁

    class DeadLockResource implements Runnable{
    
        private String lockA;
        private String lockB;
    
        public DeadLockResource(String lockA, String lockB) {
            this.lockA = lockA;
            this.lockB = lockB;
        }
    
        @Override
        public void run() {
    
            synchronized (lockA){
                System.out.println(Thread.currentThread().getName() + "	 拥有" + lockA + ",试图获取" + lockB);
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lockB){
                    System.out.println(Thread.currentThread().getName() + "	 拥有" + lockB);
                }
            }
        }
    }
    /**
     * 死锁是指两个或者两个以上的进程在执行过程中,
     * 因争夺资源而造成的一种相互等待的现象,
     * 若无外力干涉,那它们就无法推进下去,从而造成死锁现象。
     * @Author小海
     * @Description:
     * @Date: Create in 15:53 2020-02-03
     */
    public class DeadLockDemo {
        public static void main(String[] args) {
            String lockA = "lockA";
            String lockB = "lockB";
            new Thread(new DeadLockResource(lockA, lockB)).start();
            new Thread(new DeadLockResource(lockB, lockA)).start();
        }
    }
    

    5、死锁定位-DeadThread- jstack/jvisualvm/jconsole【JDK自带的命令行工具】

    1. jstack - 查看线程,主要用于线程栈分析,根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。 
      查看死锁线程的java进程id
    Linux -> ps -ef | grep DeadThread
    Window -> jps -l
    
    > jstack + 进程号
    
    1. jvisualvm - 监控程序 image
    2. jconsole - Java性能分析器

    5、预防死锁:

    1. 破坏占有且等待条件:保证一次申请所有的资源。
    2. 破坏不可抢占条件:synchronized无法做到,synchronized申请不到资源直接进入阻塞状态。 java.util.concurrent Lock可以解决此问题
    3. 破坏循环等待条件:需要对资源进行排序,然后按序申请资源
    4. 避免使用多个锁、长时间持有锁;
    5. 设计好多个锁的获取顺序
    6. 使用带超时的获取锁方法ReenTrantLock.tryLock

    6、修复死锁

    发生死锁无法在线解决,必须重启,修正程序本身的问题

     
  • 相关阅读:
    MongoCola使用教程 1 MongoDB的基本操作和聚合功能
    [教程]MongoDB 从入门到进阶 (TextSearch)
    MongoCola使用教程 2 MongoDB的Replset 初始化和配置
    [教程]MongoDB 从入门到进阶 (aggregation数据库状态)
    [教程]MongoDB 从入门到进阶 (概要 以及 高级索引篇 TimeToLive GeoNear)
    C#多线程函数如何传参数和返回值
    QQ邮箱 C# 发邮件 常见错误异常
    关于c#中的Timer控件的简单用法
    要想使用线程 想去方法 应该传入object 传参
    quartz给任务传参数以及维持任务的状态
  • 原文地址:https://www.cnblogs.com/xhyouyou/p/12465378.html
Copyright © 2011-2022 走看看