一、死锁

有A,B两把锁,t1持有A想获取B,t2持有B想获取A,导致t1 t2两个线程最终都进入阻塞状态的现象

public class Test8 {

    private final static Logger LOGGER = LoggerFactory.getLogger(Test8.class);

    private final static Object lockA= new Object();
    private final static Object lockB= new Object();

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lockA){
                    LOGGER.info("持有A");
                    synchronized (lockB){
                        LOGGER.info("持有B");
                    }
                }
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lockB){
                    LOGGER.info("持有B");
                    synchronized (lockA){
                        LOGGER.info("持有A");
                    }
                }
            }
        },"t2");

        t1.start();
        t2.start();

    }
}

如何解决:

可以使用ReentrantLock中的tryLock,或者lockInterruptibly,这些能够在某些条件下主动放弃争抢锁的方法

二、活锁

两个线程互相改变对方的结束条件,最终两个线程都不能正常结束的现象

public class Test8 {

    private final static Logger LOGGER = LoggerFactory.getLogger(Test8.class);

    private  static volatile int i=10;

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (i>0){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    i--;
                    LOGGER.info("i:"+i);

                }
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (i<20){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    i++;
                    LOGGER.info("i:"+i);

                }
            }
        },"t2");

        t1.start();
        t2.start();

    }
}

解决办法:增加随机的睡眠时间,或者t2里写i=i+20 这样t2会有更大的可能先结束,然后就没有线程修改t1的结束条件了,t1就可以结束了

三、饥饿

一个线程由于优先级太低始终抢不到cpu执行权而不能被执行,所以一直不能结束