java并发编程(3)避免活跃性危险

活跃性危险

一、死锁

  发生:每个人都不愿意放弃自己的锁,确想要别人的锁,这就会导致死锁

    1.锁顺序死锁:如果每个线程以固定的顺序获取锁,那么至少在程序中不会出现锁顺序导致的死锁;

    因为顺序固定如:所有线程:A-B-C 则无问题,如果一个A-B B-A则会发生死锁

  例子1:简单死锁

public class LeftRightDeadlock {
    private final Object left = new Object();
    private final Object right = new Object();

    public void leftRight() {
        synchronized (left) {       //锁住left
            synchronized (right) {  //锁住right
                doSomething();
            }
        }
    }
    //如果一个线程进入上面方法锁住 left,另一个线程进入下面方法锁住right,则会产生互相等待 而死锁
    public void rightLeft() {       
        synchronized (right) {      //锁住right
            synchronized (left) {   //锁住left
                doSomethingElse();
            }
        }
    }

    void doSomething() {
    }

    void doSomethingElse() {
    }
}

   例子2:转账死锁

public static void transferMoney(Account fromAccount,Account toAccount,DollarAmount amount)
            throws InsufficientFundsException {
        //转账 a-b 和 b-a ,如果同时发生,则有可能发生死锁;这种取决于参数的传入;并不是能够完全的判断得到
        synchronized (fromAccount) {
            synchronized (toAccount) {
                if (fromAccount.getBalance().compareTo(amount) < 0)
                    throw new InsufficientFundsException();
                else {
                    fromAccount.debit(amount);
                    toAccount.credit(amount);
                }
            }
        }
    }

  

  2.资源死锁

    同时获取资源,而资源却相互被锁住,就会产生死锁;

      如:一个应用有两个数据库,刚好两个线程进入两个连接池,两个连接池都满了,则需要相互等待对方释放连接

      线程饥饿死锁:表现为线程池不够,线程池内的线程相互等待(A提交B到单线程池,右提交C到单线程池,但是B要等待C完成才能执行)

  3.活锁

    不会阻塞线程,但是也不能继续执行

    类似于程序不断尝试不断失败,永远无法跳出来

原文地址:https://www.cnblogs.com/zhangxinly/p/6909730.html