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、修复死锁

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

     
  • 相关阅读:
    oracle 数据库、实例、服务名、SID
    查看oracle数据库服务器的名字
    oracle表复制
    Oracle 备份、恢复单表或多表数据步骤
    如何查询一个表中有哪些列全为空
    mysql当查询某字段结果为空并赋值
    NoSQL初探之人人都爱Redis:(1)Redis简介与简单安装
    《大型网站技术架构》读书笔记四:瞬时响应之网站的高性能架构
    《大型网站技术架构》读书笔记三:大型网站核心架构要素
    《大型网站技术架构》读书笔记二:大型网站架构模式
  • 原文地址:https://www.cnblogs.com/xhyouyou/p/12465378.html
Copyright © 2011-2022 走看看