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、活锁
活锁不会阻塞线程,但是线程不能继续执行。因为线程一直在执行重复的操作,但是总会丢失。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。