title: Threaded bank transfer simulation and synchronization
body: <p>I have following situation. I have a class for accounts, each account has a balance and money can be transfered to it.</p>
  
  <pre><code>public class Account {
      private int balance;
  
      public Account() {
          this.balance = 0;
      }
  
      public void transfer(int amount) {
          this.balance += amount;
      }
  
      @Override
      public String toString() {
          return "Account (balance: " + balance + ")";
      }
  }
  </code></pre>
  
  <p>And I have a transfer manager. A transfer simply takes two accounts and a amount of money to be transfered. The transfer manager can issue transfers by adding it to the array list, kind of transfer queue. After all transfers are added to the queue the performTransfers method can be called which calles the performTransfer method on every transfer. </p>
  
  <pre><code>import java.util.ArrayList;
  
  public class TransferManager {
      private ArrayList&lt;Transfer&gt; openTransfers;
      private int issuedTransfers;
      private int performedTransfers;
  
      public TransferManager() {
          openTransfers = new ArrayList&lt;Transfer&gt;();
          issuedTransfers = 0;
          performedTransfers = 0;
      }
  
      public void issueTransfer(Account from, Account to, int amount) {
          openTransfers.add(new Transfer(from, to, amount));
          issuedTransfers++;
      }
  
      public void performTransfers() {
          for(Transfer transaction : openTransfers) {
              transaction.performTransfer();
              performedTransfers++;
          }       
          openTransfers.clear();
      }
  
      @Override
      public String toString() {
          return "TransferManager (openTransfers: " + openTransfers.size() + "; issuedTransfers: " + issuedTransfers + "; performedTransfers: " + performedTransfers + ")";
      }
  
      private static class Transfer {
          private Account from, to;
          private int amount;
  
          public Transfer(Account from, Account to, int amount) {
              this.from = from;
              this.to = to;
              this.amount = amount;
          }
  
          public void performTransfer() {
              from.transfer(-amount);
              to.transfer(amount);
          }
      }
  }
  </code></pre>
  
  <p>Now I add multithreading:</p>
  
  <pre><code>import java.util.Random;
  
  public class BankingTest extends Thread {
      private Account[] accounts;
      private static Random random = new Random();
  
      public BankingTest(Account[] accounts) {
          this.accounts = accounts;
      }
  
      public void run() {
          final TransferManager manager = new TransferManager();
  
          //simulate some transfers
          for(int i = 0; i &lt; accounts.length; i++) {
              final int index = i;
              Thread thread = new Thread() {
                  public void run() {
                      try {
                          for(int j = 0; j &lt; 10; j++) {
                              manager.issueTransfer(accounts[index], accounts[(index+1)%accounts.length], 100);
                              Thread.sleep(random.nextInt(10));
                          }
                      } catch (InterruptedException e) {                      
                          e.printStackTrace();
                      }
                  }
              };
              thread.start();
          }
  
          //wait a bit
          try {
              Thread.sleep(60);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
  
          manager.performTransfers();
  
          System.out.println(manager);
      }
  }
  </code></pre>
  
  <p>BankingTest takes an array of say 10 blank accounts. For now it is not synchronized and I try to understand why I get those errors:</p>
  
  <pre><code>Exception in thread "Thread-2" java.lang.NullPointerException
  at
  gp2.ha5.exercise2.TransferManager.performTransfers(TransferManager.java:23)
  at gp2.ha5.exercise2.BankingTest.run(BankingTest.java:41)
  
  and
  
  TransferManager (openTransfers: 0; issuedTransfers: 99; performedTransfers:
  99)
  </code></pre>
  
  <p>Any idea why I get those errors and how can synchronization help here?</p>
  
  <p><img src="https://i.stack.imgur.com/FWuto.png" alt="enter image description here"></p>
  
  <p>(you can zoom in to see the details ;))</p>
  
  <p>TransferManager: <a href="http://pastebin.com/Je4ExhUz" rel="nofollow noreferrer">http://pastebin.com/Je4ExhUz</a></p>
  
  <p>BankTest: <a href="http://pastebin.com/cdpWhHPb" rel="nofollow noreferrer">http://pastebin.com/cdpWhHPb</a></p>
  
  <p>Start: <a href="http://pastebin.com/v7pwJ5T1" rel="nofollow noreferrer">http://pastebin.com/v7pwJ5T1</a></p>
  
  <hr>
  
  <p>After I added the synchronized to issueTransfer and performTransfers method I keep getting errors:</p>
  
  <p><img src="https://i.stack.imgur.com/H4ai1.png" alt="enter image description here"></p>