—— 24.5.
一、死锁
1.死锁介绍(锁嵌套就有可能产生死锁)
指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁
例:
两线程处于互相等待的状态,就是死锁在程序中的死锁出现在同步代码块的嵌套中,这种情况下同样有很小的可能不出现死锁,以后尽量避免锁嵌套
2.死锁状态
LockA
java">package S75DieLock;public class LockA {// 定义一个锁对象public static LockA lockA = new LockA(); }
LockB
java">package S75DieLock;public class LockB {// 定义一个锁对象public static LockB lockB = new LockB(); }
死锁DieLock
java">package S75DieLock;public class DieLock implements Runnable{private boolean flag;public DieLock(boolean flag){this.flag = flag;}@Override// 重写run方法public void run(){if (flag){synchronized (LockA.lockA){System.out.println("if ... lockA");synchronized (LockB.lockB){System.out.println("if ... lockB");}}}else {// 套件锁Asynchronized (LockB.lockB){System.out.println("else ... lockB");synchronized (LockA.lockA){System.out.println("if ... lockA");}}}} }
测试类
java">package S75DieLock;public class Demo214Test {public static void main(String[] args) {DieLock dieLock1 = new DieLock(true);DieLock dieLock2 = new DieLock(false);new Thread(dieLock1).start();new Thread(dieLock2).start();} }
有时也会产生一个进程率先进入打开了所有锁的状态
二、线程状态
1.线程状态介绍
①sleep(time)和wait(time)有啥区别?
a.sleep(time):线程睡眠,在睡眠的过程中,线程是不会释放锁,此时其他线程抢不到锁,设置的时间旦超时,自动醒来,继续执行
b.wait(time):线程等待,在等待的过程中会释放锁,其他线程就有可能抢到锁,如果在等待的过程中被唤醒或者时间超时,会和其他的线程重新抢锁,如果抢到了继续执行,抢不到,锁阻塞②wait()和notify():
a.wait():空参wait,线程进入到无限等待状态,会释放锁,需要其他线程调用notify(一次唤醒一条等待的线程,唤醒是随机的)或者notifyAII方法(将所有等待线程全唤醒),被唤醒之后,会和其他的线程重新抢锁,抢到了,继续执行;抢不到,锁阻塞
b.notify():notify会唤醒正在等待的线程,一次只能唤醒一条等待的线程;如果要是多条线程在等待,notify会随机一条唤醒;
c.notifyAll():唤醒所有等待的线程③wait()和notify()两个方法的用法:
a.两个方法都需要锁对象调用,所以两个方法需要用到同步代码块,同步方法中
b.两个方法的调用必须是同一个锁对象调用可以理解为用同一个锁对象,将多条线程分到了一组中,这样notify就知道唤醒的是自己本组的等待线程