并发死锁示例

8 篇文章 0 订阅

初始

死锁是指两个或者两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去。

如图:
在这里插入图片描述

  1. 线程A已经持有了资源2,他同时还想申请资源1
  2. 线程B已经持有了资源1,它同时还想申请资源2

所以两个线程相互等待对方已经持有的资源而进入了死锁状态。

死锁产生并备的四个条件

  • 互斥条件

    指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。

  • 请求并持有条件

    指一个线程已经持有了一个资源,但又提出了新的资源请求,而新资源已被其他线程占用,所有当前线程会被阻塞,但阻塞的同时并不释放自己已经获取的资源。

  • 不可剥夺条件

    指线程获取到的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完毕之后才由自己释放该资源。

  • 环路等待条件

    指在发生死锁时,必然存在一个线程一资源的环形链,即线程1等线程2占用的资源,线程2等线程3占用的资源,…线程n等待线程1占用的资源。

代码示例

public class DeadLockDemo {
	private static Object resourceA = new Object();
	private static Object resourceB = new Object();

	public static void main(String[] args) {
		new Thread(() -> {
			synchronized (resourceA) {
				System.out.println(Thread.currentThread() + "get resourceA");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread() + "waiting get resourceB");
				synchronized (resourceB) {
					System.out.println(Thread.currentThread() + "get resourceB");
				}
			}
		}).start();

		new Thread(() -> {
			synchronized (resourceB) {
				System.out.println(Thread.currentThread() + "get resourceB");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread() + "waiting get resourceA");
				synchronized (resourceA) {
					System.out.println(Thread.currentThread() + "get resourceA");
				}
			}
		}).start();
	}
}

/*返回
Thread[Thread-0,5,main]get resourceA
Thread[Thread-1,5,main]get resourceB
Thread[Thread-1,5,main]waiting get resourceA
Thread[Thread-0,5,main]waiting get resourceB
*/

查看死锁进程

>jps
38324 DeadLockDemo
>jstack 38324
"Thread-1" #10 prio=5 os_prio=0 tid=0x15472000 nid=0x35e0 waiting for monitor entry [0x1581f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.syq.demo.concurrent.DeadLockDemo.lambda$main$1(DeadLockDemo.java:39)
        - waiting to lock <0x04d0bd68> (a java.lang.Object)
        - locked <0x04d0bd70> (a java.lang.Object)
        at com.syq.demo.concurrent.DeadLockDemo$$Lambda$2/19993396.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

"Thread-0" #9 prio=5 os_prio=0 tid=0x15471c00 nid=0x92c waiting for monitor entry [0x1578f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.syq.demo.concurrent.DeadLockDemo.lambda$main$0(DeadLockDemo.java:24)
        - waiting to lock <0x04d0bd70> (a java.lang.Object)
        - locked <0x04d0bd68> (a java.lang.Object)
        at com.syq.demo.concurrent.DeadLockDemo$$Lambda$1/17290025.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

避免死锁

避免死锁,只需要破坏掉至少一个必要条件即可。

只有请求并持有条件和环路等待条件是可以破坏的。

我们可以让资源有序性,即每个线程都是先得到资源1在去拿资源2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值