1 package book.jcp.ch10.avail;
2
3 import java.util.Random;
4 import java.util.concurrent.TimeUnit;
5
6 public class TryLockDemonstrateDeadLock {
7
8 private final static int NUM_THREADS = 20;
9 private final static int NUM_ACCOUNTS = 5;
10 private final static int NUM_ITERATIONS = 1000000;
11
12 private static boolean transferMoney(Account fromAccount,
13 Account toAccount, Long amount, long timeout, TimeUnit timeUnit)
14 throws InsufficientFundsException, InterruptedException {
15
16 long fixedDelay = getFixedDelayComponentNanos(timeout, timeUnit);
17 long randMod = getRandomDelayModulusNanos(timeout, timeUnit);
18 long stopTime = System.nanoTime() + timeUnit.toNanos(timeout);
19
20 while (true) {
21 if (fromAccount.lock.tryLock()) {
22 try {
23 if (toAccount.lock.tryLock()) {
24 try {
25 if (fromAccount.getBalance().compareTo(amount) < 0) {
26 throw new InsufficientFundsException();
27 } else {
28 fromAccount.debit(amount);
29 toAccount.credit(amount);
30 return true;
31 }
32 } finally {
33 toAccount.lock.unlock();
34 }
35 }// if
36 } finally {
37 fromAccount.lock.unlock();
38 }
39 }// if
40
41 if (System.nanoTime() < stopTime) {
42 return false;
43 }
44 TimeUnit.NANOSECONDS.sleep(fixedDelay + new Random().nextLong()
45 % randMod);
46 }// while
47
48 }
49
50 private static long getFixedDelayComponentNanos(long timeout,
51 TimeUnit timeUnit) {
52 // TODO Auto-generated method stub
53 return 0;
54 }
55
56 private static long getRandomDelayModulusNanos(long timeout,
57 TimeUnit timeUnit) {
58 // TODO Auto-generated method stub
59 return 0;
60 }
61
62 public static void main(String[] args) {
63 final Random rand = new Random();
64 final Account[] accounts = new Account[NUM_ACCOUNTS];
65
66 for (int i = 0; i < NUM_ACCOUNTS; i++) {
67 accounts[i] = new Account();
68 }
69
70 class TransferThread extends Thread {
71 @Override
72 public void run() {
73 for (int i = 0; i < NUM_ITERATIONS; i++) {
74 System.out.println("-------------------" + "[ThreadId : "
75 + currentThread().getId() + " Iteration : " + i
76 + "]-------------------");
77 int fromAccount = rand.nextInt(NUM_ACCOUNTS);
78 int toAccount = rand.nextInt(NUM_ACCOUNTS);
79 Long amount = Math.abs(rand.nextLong() % 10000);
80 try {
81 transferMoney(accounts[fromAccount],
82 accounts[toAccount], amount, 10,
83 TimeUnit.MICROSECONDS);
84 } catch (InsufficientFundsException e) {
85 e.printStackTrace();
86 } catch (InterruptedException e) {
87 // TODO Auto-generated catch block
88 e.printStackTrace();
89 }
90
91 }
92 }
93 }
94
95 for (int i = 0; i < NUM_THREADS; i++) {
96 new TransferThread().start();
97 }
98 }
99
100 }