例如: 在银⾏系统转账时,需要锁定两个账户,这个时候,顺序使⽤两个synchronized可能存在死锁的情况,在⽹上搜索到下⾯的例⼦:

1 public class Bank {
2 final static Object obj_lock = new Object();
3
4 // Deadlock crisis 死锁
5 public void transferMoney(Account from, Account to, int number) {
6 synchronized (from) {
7 synchronized (to) {
8 from.debit();
9 to.credit();
10 }
11 }
12 }
13
14 // Thread safe
15 public void transferMoney2(final Account from, final Account to, int number) {
16 class Help {
17 void transferMoney2() {
18 from.debit();
19 to.credit();
20 }
21 }
22
23 //通过hashCode⼤⼩调整加锁顺序
24 int fromHash = from.hashCode();
25 int toHash = to.hashCode();
26
27 if (fromHash < toHash) {
28 synchronized (from) {
29 synchronized (to) {
30 new Help().transferMoney2();
31 }
32 }
33 } else if (toHash < fromHash) {
34 synchronized (to) {
35 synchronized (from) {
36 new Help().transferMoney2();
37 }
38 }
39 } else {
40 synchronized (obj_lock) {
41 synchronized (to) {
42 synchronized (from) {
43 new Help().transferMoney2();
44 }
45 }
46 }
47 }
48 }
49 }

若操作账户A,B:

  1. A的hashCode⼩于B, 先锁A再锁B
  2. B的hashCode⼩于A, 先锁B再锁A
  3. 产⽣的hashCode相等,先锁住⼀个全局静态变量,在锁A,B 这样就避免了两个线程分别操作账户A,B和B,A⽽产⽣死锁的情况。需要为Account对象写⼀个好的hashCode算法,使得不同账户间产⽣的hashCode尽量不同。