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