Lecture Videos
  1  import java.util.concurrent.*;
  2  import java.util.concurrent.locks.*;
  3  
  4  public class ThreadCooperation {
  5    private static Account account = new Account();
  6  
  7    public static void main(String[] args) {
  8      // Create a thread pool with two threads
  9      ExecutorService executor = Executors.newFixedThreadPool(2);
 10      executor.execute(new DepositTask());
 11      executor.execute(new WithdrawTask());
 12      executor.shutdown();
 13  
 14      System.out.println("Thread 1\t\tThread 2\t\tBalance");
 15    }
 16  
 17    public static class DepositTask implements Runnable {
 18      @Override // Keep adding an amount to the account
 19      public void run() {
 20        try { // Purposely delay it to let the withdraw method proceed
 21          while (true) {
 22            account.deposit((int)(Math.random() * 10) + 1);
 23            Thread.sleep(1000);
 24          }
 25        }
 26        catch (InterruptedException ex) {
 27          ex.printStackTrace();
 28        }
 29      }
 30    }
 31  
 32    public static class WithdrawTask implements Runnable {
 33      @Override // Keep subtracting an amount from the account
 34      public void run() {
 35        while (true) {
 36          account.withdraw((int)(Math.random() * 10) + 1);
 37        }
 38      }
 39    }
 40  
 41    // An inner class for account
 42    private static class Account {
 43      // Create a new lock
 44      private static Lock lock = new ReentrantLock();
 45  
 46      // Create a condition
 47      private static Condition newDeposit = lock.newCondition();
 48  
 49      private int balance = 0;
 50  
 51      public int getBalance() {
 52        return balance;
 53      }
 54  
 55      public void withdraw(int amount) {
 56        lock.lock(); // Acquire the lock
 57        try {
 58          while (balance < amount) {
 59            System.out.println("\t\t\tWait for a deposit");
 60            newDeposit.await();
 61          }
 62          
 63          balance -= amount;
 64          System.out.println("\t\t\tWithdraw " + amount +
 65            "\t\t" + getBalance());
 66        }
 67        catch (InterruptedException ex) {
 68          ex.printStackTrace();
 69        }
 70        finally {
 71          lock.unlock(); // Release the lock
 72        }
 73      }
 74  
 75      public void deposit(int amount) {
 76        lock.lock(); // Acquire the lock
 77        try {
 78          balance += amount;
 79          System.out.println("Deposit " + amount +
 80            "\t\t\t\t\t" + getBalance());
 81  
 82          // Signal thread waiting on the condition
 83          newDeposit.signalAll();
 84        }
 85        finally {
 86          lock.unlock(); // Release the lock
 87        }
 88      }
 89    }
 90  }