Java中死锁之代码演示和检测

简介

本文将通过Java代码演示一个死锁程序,并用JDK自带的工具jstack工具,来验证下是否真正的有死锁发生。

一.什么是死锁

两个或两个以上的线程,互相持有对方需要的资源,导致这些线程一直处于“等待”(WAITING)状态。

二.死锁的代码演示

本例演示两个线程,互相竞争对方的对象锁,造成的死锁。

public class DeadLock implements Runnable {

	int condition;
	static Object object1 = new Object();
	static Object object2 = new Object();

	public static void main(String[] args) {
		DeadLock deadLock1 = new DeadLock();
		DeadLock deadLock2 = new DeadLock();
		deadLock1.condition = 1;
		deadLock2.condition = 2;

		Thread t1 = new Thread(deadLock1);
		Thread t2 = new Thread(deadLock2);

		t1.start();
		t2.start();
	}

	@Override
	public void run() {
		System.out.println("当前是线程:" + condition);
		if (condition == 1) {
			synchronized (object1) {
				System.out.println("线程1" + "得到object1锁");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("线程1,卡在下一行代码");
				synchronized (object2) {
					System.out.println("打印出此行,表示线程1同时获得两把锁");
				}
				System.out.println("线程1执行完毕");
			}
		}
		if (condition == 2) {
			synchronized (object2) {
				System.out.println("线程2" + "得到object2锁");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("线程2,卡在下一行代码");
				synchronized (object1) {
					System.out.println("打印出此行,表示线程2同时获得两把锁");
				}
				System.out.println("线程2执行完毕");
			}
		}
	}
}

运行结果:
当前是线程:1
当前是线程:2
线程2得到object2锁
线程1得到object1锁
线程1,卡在下一行代码
线程2,卡在下一行代码
运行结果分析:
  1. 线程1持有了object1的锁,线程2持有了object2的锁。
  2. 然后线程1去竞争object2锁;线程2去竞争object1锁。
  3. 由于线程1并没有释放object1锁,线程2也并没有释放object2锁,所以会造成死锁。

三.验证是否真正死锁

在命令行中输入:jps,查到我们代码程序的进程号为6164
在这里插入图片描述

然后在命令行再输入:jstack -l 6164,分析下程序状态:
在这里插入图片描述

发现程序中出现了死锁现象。

总结

明白了死锁发生的机制,我们可以想办法避免死锁发生,第一种方法是注意加锁顺序,在上面的代码实例中,我们只要在两个线程中,
对锁的竞争顺序保持一致(比如两个线程都是先竞争object1锁,再竞争object2锁),那死锁就不会出现了。第二种避免死锁的方式是,
设置超时时间,如果超过一定时间,自动释放锁。

在程序运行时,我们可以通过jstack工具,查看程序运行状态,是否有死锁。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值