1、死锁

①什么是死锁?

双方因为互相等待对方的资源而进入了循环等待的过程

②产生死锁的条件?

1、环路等待

2、持有并等待

3、互斥

4、不剥夺

必须满足以上4个条件,才会产生死锁

④示例代码

public static void main(String[] args) {
    new T1().start();
    new T2().start();
}

static class T1 extends Thread {

    @Override
    public void run() {
        a();
    }

    public void a() {
        while (true) {
            synchronized (T1.class) {
                synchronized (T2.class) {
                    System.out.println("a");
                }
            }
        }
    }
}

static class T2 extends Thread {
    @Override
    public void run() {
        b();
    }

    public void b() {
        while (true) {
            synchronized (T2.class) {
                synchronized (T1.class) {
                    System.out.println("b");
                }
            }
        }
    }
}

解释:

互斥:T1和T2存在锁互斥条件

环路等待及持有并等待:T1持有T1锁,等待T2锁;T2持有T2锁,等待T1锁。

操作系统的不剥夺~~

⑤死锁的检测工具

jconsole  // 可直接检测死锁
jstack // 查看线程堆栈信息

⑥死锁的解决方法

1、同样的加锁顺序

2、加锁限时,例如使用Lock


2、线程饥饿

①什么是线程饥饿?

线程饥饿是指线程得不到运行

②为什么会产生线程饥饿?

1、高优先级线程抢占低优先级线程的CPU时间片,导致低优先级线程无法执行

2、线程被永久阻塞在等待进入同步块的状态,其他线程总是能在该线程之前持续对该同步块进行访问

③解决方案

1、避免使用优先级

2、使用公平锁


3、活锁

活锁不会阻塞线程,但是线程不能继续执行。因为线程一直在执行重复的操作,但是总会丢失。


心无私天地宽
513 声望22 粉丝