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 }