网站建设中倒计时模板,软件商店app下载安装,免费做调查的网站,棒的网页设计死锁是指两个或两个以上的进程#xff08;线程#xff09;在执行过程中#xff0c;由于竞争资 源或者由于彼此通信而造成的一种阻塞的现象#xff0c;若无外力作用#xff0c;它们都将无法推 进下去。此时称系统处于死锁状态或系统产生了死锁#xff0c;这些永远在互相… 死锁是指两个或两个以上的进程线程在执行过程中由于竞争资 源或者由于彼此通信而造成的一种阻塞的现象若无外力作用它们都将无法推 进下去。此时称系统处于死锁状态或系统产生了死锁这些永远在互相等待的进 程线程称为死锁进程线程。 多个线程同时被阻塞它们中的一个或者全部都在等待某个资源被释放。由于线 程被无限期地阻塞因此程序不可能正常终止。 如下图所示线程 A 持有资源 2线程 B 持有资源 1他们同时都想申请对方 的资源所以这两个线程就会互相等待而进入死锁状态。 下面通过一个例子来说明线程死锁代码模拟了上图的死锁的情况 public class DeadLockDemo {private static final Object resource1 new Object();//资源 1private static final Object resource2 new Object();//资源 2public static void main(String[] args) {new Thread(() - {synchronized (resource1) {System.out.println(Thread.currentThread().getName() get resource1);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() waiting get resource2);synchronized (resource2) {System.out.println(Thread.currentThread().getName() get resource2);}}}, 线程 1---).start();new Thread(() - {synchronized (resource2) {System.out.println(Thread.currentThread().getName() get resource2);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() waiting get resource1);synchronized (resource1) {System.out.println(Thread.currentThread().getName() get resource1);}}}, 线程 2---).start();}
}输出结果
线程 1---get resource1
线程 2---get resource2
线程 2---waiting get resource1
线程 1---waiting get resource2 线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁然后通 过 Thread.sleep(1000) 让线程 A 休眠 1s 为的是让线程 B 得到CPU执行权然 后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求 获取对方的资源然后这两个线程就会陷入互相等待的状态这也就产生了死 锁。上面的例子符合产生死锁的四个必要条件。 形成死锁的四个必要条件是什么 1. 互斥条件线程(进程)对于所分配到的资源具有排它性即一个资源只 能被一个线程(进程)占用直到被该线程(进程)释放 2. 请求与保持条件一个线程(进程)因请求被占用资源而发生阻塞时对 已获得的资源保持不放。 3. 不剥夺条件线程(进程)已获得的资源在末使用完之前不能被其他线程 强行剥夺只有自己使用完毕后才释放资源。 4. 循环等待条件当发生死锁时所等待的线程(进程)必定会形成一个环 路类似于死循环造成永久阻塞 如何避免线程死锁 我们只要破坏产生死锁的四个条件中的其中一个就可以了。 破坏互斥条件 这个条件我们没有办法破坏因为我们用锁本来就是想让他们互斥的临界资源 需要互斥问。 破坏请求与保持条件 一次性申请所有的资源。 破坏不剥夺条件 占用部分资源的线程进一步申请其他资源时如果申请不到可以主动释放它占 有的资源。 破坏循环等待条件 靠按序申请资源来预防。按某一顺序申请资源释放资源则反序释放。破坏循环 等待条件。 我们对线程 2 的代码修改成下面这样就不会产生死锁了。 new Thread(() - {synchronized (resource1) {System.out.println(Thread.currentThread().getName() get resource1);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() waiting get resource2);synchronized (resource2) {System.out.println(Thread.currentThread().getName() get resource2);}}
}, 线程 2---).start(); 输出结果 线程 1---get resource1
线程 1---waiting get resource2
线程 1---get resource2
线程 2---get resource1
线程 2---waiting get resource2
线程 2---get resource2 我们分析一下上面的代码为什么避免了死锁的发生? 线程 1 首先获得到 resource1 的监视器锁这时候线程 2 就获取不到了。然后 线程 1 再去获取 resource2 的监视器锁可以获取到。然后线程 1 释放了对 resource1、resource2 的监视器锁的占用线程 2 获取到就可以执行了。这样 就破坏了破坏循环等待条件因此避免了死锁。