java死锁示例及其发现方法

在java多线程编程中很容易出现死锁,死锁就是多个线程相互之间永久性的等待对方释放锁,这和数据库多个会话之间的死锁类似。下面的代码示例了一个最简单的死锁的例子,线程1和线程2相互之间等待对方释放锁来取得cpu执行权。

 

class DeadLockTest implements Runnable{
	
	private String str;
	
	private Object lock1 = new Object();
	
	private Object lock2 = new Object();
	
	public void run()
	{
		if(str.equals("a"))
		{
			synchronized(lock1)
			{
				try {
					System.out.println("str is a ! thread-name:" + Thread.currentThread().getName());
					Thread.sleep(3000l);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (lock2) {
					System.out.println("lock1 -- > lock2 !");
				}
			}
		}
		if(str.equals("b")) {
			synchronized (lock2) {
				System.out.println("str is b ! thread-name:" + Thread.currentThread().getName());
				synchronized (lock1) {
					System.out.println("lock2 -- > lock1 !");
				}
			}
		}
			
	}

	public String getStr() {
		return str;
	}

	public void setStr(String str) {
		this.str = str;
	}
	
	
}

main方法代码:

public class LockReGetDemo {
	public static void main(String[] args) throws InterruptedException {
		DeadLockTest deadLock = new DeadLockTest();
		Thread t1 = new Thread(deadLock);
		deadLock.setStr("a");
		t1.setName("A");
		t1.start();
		Thread.sleep(500l);
		Thread t2 = new Thread(deadLock);
		t2.setName("B");
		deadLock.setStr("b");
		t2.start();
	}
}

运行后你会发现,打印结果如下,后面的内容一致不会打印,并且程序一直处于等待状态:

str is a ! thread-name:A
str is b ! thread-name:B

那么如何检测死锁呢? 在jvm中给我们提供了一些使用的工具,比如jps和jstack,jps用来查看运行的进程及其id,jstack用来查看具体线程id的运行信息,在上面的死锁例子中,我们进入jvm安装的bin目录,控制台运行jps命令:

 

然后使用jstack命令查看进程信息

这样就可以知道哪里出现了死锁。

 原文链接:http://www.j2eeweb.com/front/get?id=5c4eb0903c517020beb2539e

posted @ 2019-01-28 15:32  499755609  阅读(194)  评论(0编辑  收藏  举报