zoukankan      html  css  js  c++  java
  • Java-死锁

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

    例子:哲学家进餐问题

    死锁产生的必要条件:

    1. 互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直到占有该资源的进程使用完后释放该资源。
    2. 请求和保持:进程获得一定资源后,可以对其他资源发出获取请求,但同时对自己已经获得的资源保持不放
    3. 不可剥夺条件:进程已经获得的资源,在未完成使用之前,不可以被剥夺,只能在使用完成之后自己释放。
    4. 循环等待:进程发生死锁后,必然存在一个进程-资源之间环形链。

    破坏产生死锁的任何一个必要条件都可以消除死锁现象。

    写一个简单的死锁程序:

    package com.fpc.Test;
    class thread1 implements Runnable {
        private DeadLock deadlock;
        
        //构造函数
        public thread1( DeadLock deadlock ) {
            this.deadlock = deadlock;
        }
        
        @Override
        public void run( ) {
            try {
                deadlock.lock1toLock2();
            } catch( Exception e ) {
                e.printStackTrace();
            }
        }
    }
    
    class thread2 implements Runnable {
        private DeadLock deadlock;
        
        //构造函数
        public thread2( DeadLock deadlock ) {
            this.deadlock = deadlock;
        }
        
        @Override
        public void run( ) {
            try {
                deadlock.lock2toLock1();
            } catch( Exception e ) {
                e.printStackTrace();
            }
        }
    }
    
    public class DeadLock {
        private Object lock1 = new Object();
        private Object lock2 = new Object();
        
        public void lock1toLock2() {
            synchronized( lock1 ) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized( lock2 ) {
                    System.out.println("lock1toLock2 end.....");
                }
            }
        }
        
        public void lock2toLock1() {
            synchronized( lock2 ) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized( lock1 ) {
                    System.out.println("lock2toLock1 end.....");
                }
            }
        }
        
        public static void main( String[] args ) {
            DeadLock d = new DeadLock();
            thread1 t1 = new thread1(d);
            thread2 t2 = new thread2(d);
            Thread th1 = new Thread(t1);
            Thread th2 = new Thread(t2);
            th1.start();
            th2.start();
        }
    }

    怎么去分析死锁:

    先用jps命令查看虚机中运行的Java线程的pid:

    然后根据pid 去查看 jstack pid:

    避免死锁的方式

    1.设计时考虑清楚锁的顺序,尽量减少嵌套的加锁交互数量

    2.死锁产生的原因是资源的循环等待,那么给获取锁加个时间限制,超过一定的时间还没有获取到对象的锁,那么就释放已经获取的对象的锁。当然synchronized是无法做到的,可以用可重入锁ReentrantLock

    针对上面的程序可以这么改:

    public void lock1toLock2() throws InterruptedException {
            if (lock1.tryLock(3000, TimeUnit.MILLISECONDS)){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    if ( lock2.tryLock(3000, TimeUnit.MICROSECONDS) ) {
                        System.out.println("lock1toLock2 end.....");
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
          }
        }

    运行再次查看jps:可以看到没有出现DeadLock线程了,嗯,不会出现死锁了

  • 相关阅读:
    Codeforces Round #649 (Div. 2) D. Ehab's Last Corollary
    Educational Codeforces Round 89 (Rated for Div. 2) E. Two Arrays
    Educational Codeforces Round 89 (Rated for Div. 2) D. Two Divisors
    Codeforces Round #647 (Div. 2) E. Johnny and Grandmaster
    Codeforces Round #647 (Div. 2) F. Johnny and Megan's Necklace
    Codeforces Round #648 (Div. 2) G. Secure Password
    Codeforces Round #646 (Div. 2) F. Rotating Substrings
    C++STL常见用法
    各类学习慕课(不定期更新
    高阶等差数列
  • 原文地址:https://www.cnblogs.com/fangpengchengbupter/p/9262522.html
Copyright © 2011-2022 走看看