分析Java死锁:分析jstack日志
本文中我将展示一段垃圾代码,这段代码会产生死锁,这样围绕这段代码重点展示三种不同的方法来分析线程日志,从而得知什么地方有问题。下面的讨论将用到两个类 Account 和 DeadlockDemo classes 定义如下:public class Account {private final int number;private int balance;public Account(int number, int openingBalance) {this.number = number;this.balance = openingBalance;}public void withdraw(int amount) throws OverdrawnException {if (amount > balance) {throw new OverdrawnException();}balance -= amount;}public void deposit(int amount) {balance += amount;}public int getNumber() {return number;}public int getBalance() {return balance;}}The above class models a bank account with attributes of account number and balance, and operations such as deposit(...) and withdraw(...). withdraw(...) will throw a 易做图 checked exception, OverdrawnException, if the amount to withdraw is greater than the available balance.The remaining classes in the example code are DeadlockDemo and its nested class BadTransferOperation.public class DeadlockDemo {private static final int NUM_ACCOUNTS = 10;private static final int NUM_THREADS = 20;private static final int NUM_ITERATIONS = 100000;private static final int MAX_COLUMNS = 60;static final Random rnd = new Random();List<Account> accounts = new ArrayList<Account>();public static void main(String args[]) {DeadlockDemo demo = new DeadlockDemo();demo.setUp();demo.run();}void setUp() {for (int i = 0; i < NUM_ACCOUNTS; i++) {Account account = new Account(i, rnd.nextInt(1000));accounts.add(account);}}void run() {for (int i = 0; i < NUM_THREADS; i++) {new BadTransferOperation(i).start();}}class BadTransferOperation extends Thread {int threadNum;BadTransferOperation(int threadNum) {this.threadNum = threadNum;}@Overridepublic void run() {for (int i = 0; i < NUM_ITERATIONS; i++) {Account toAccount = accounts.get(rnd.nextInt(NUM_ACCOUNTS));Account fromAccount = accounts.get(rnd.nextInt(NUM_ACCOUNTS));int amount = rnd.nextInt(1000);if (!toAccount.equals(fromAccount)) {try {transfer(fromAccount, toAccount, amount);System.out.print(".");} catch (OverdrawnException e) {System.out.print("-");}printNewLine(i);}}// This will never get to here...System.out.println("Thread Complete: " + threadNum);}private void printNewLine(int columnNumber) {if (columnNumber % MAX_COLUMNS == 0) {System.out.print("\n");}}/*** The clue to spotting deadlocks is in the nested locking - synchronized keywords. Note that the locks DON'T* have to be next to each other to be nested.*/private void transfer(Account fromAccount, Account toAccount, int transferAmount) throws OverdrawnException {synchronized (fromAccount) {synchronized (toAccount) {fromAccount.withdraw(transferAmount);toAccount.deposit(transferAmount);}}}}}首先拿到线程日志当运行程序 DeadlockDemo,日志如下:2012-10-16 13:37:03Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.10-b01-428 mixed mode):"DestroyJavaVM" prio=5 tid=7f9712001000 nid=0x110247000 waiting on condition [00000000]java.lang.Thread.State: RUNNABLE"Thread-21" prio=5 tid=7f9712944000 nid=0x118d76000 waiting for monitor entry [118d75000]java.lang.Thread.State: BLOCKED (on object monitor)at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)- waiting to lock <7f3366f58> (a threads.deadlock.Account)- locked <7f3366ee0> (a threads.deadlock.Account)at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-20" prio=5 tid=7f971216c000 nid=0x118c73000 waiting for monitor entry [118c72000]java.lang.Thread.State: BLOCKED (on object monitor)at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)- waiting to lock <7f3366e98> (a threads.deadlock.Account)- locked <7f3366f58> (a threads.deadlock.Account)at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-19" prio=5 tid=7f9712943800 nid=0x118b70000 waiting for monitor entry [118b6f000]java.lang.Thread.State: BLOCKED (on object monitor)at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)- waiting to lock <7f3366f40> (a threads.deadlock.Account)at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:5补充:软件开发 , Java ,
上一个:java使用batik转换svg文件
下一个:java对文件拷贝的简单操作
- 更多JAVA疑问解答:
- java怎么在线读取ftp服务器上的文件内容
- 关于程序员的职业规划
- HTML和JSP矛盾吗?
- java小程序如何打包?
- java怎么split路径文件名?
- jsp+javaBean中Column 'ordersPrice' specified twice的错误
- Java TCP/IP Socket网络编程系列
- 大家来讨论一下我到底该用什么好?Swing 还是 JavaFX
- 关于Hibernate实体自身多对一的抓取问题
- 关于apache2+tomcat群集出现的问题
- spring 获取上下文问题
- SSH 导入导出excel 谁有这块的资料吗?
- Ext TreePanel 刷新问题
- springmvc 加载一个jsp页面执行多个方法 报404
- checkbox数组action怎么向页面传值