2015-07-10 113 views
0

我编写了以下代码以实现正确行为的金额转帐方案。即使在每个方法上添加同步之后,在运行程序一段时间后,仍然会看到“系统不一致”错误。我不知道为什么我这样做。这里的任何帮助表示赞赏。帐户之间的多线程银行转帐

我写了下面的代码来实现正确的行为量转移方案。即使在每个方法上添加同步之后,在运行程序一段时间后,仍然会看到“系统不一致”错误。我不知道为什么我这样做。这里的任何帮助表示赞赏。

包并发;

public class MoneyTransfer { 

     static void makeTransfer(Account fromAccount, Account toAccount, long amount) { 

      synchronized(MoneyTransfer.class) { 
       fromAccount.withdraw(amount); 
       toAccount.deposit(amount); 
      } 
     } 

     public static void main(String a[]) { 

      Account accA = new Account("a", 1000000); 
      Account accB = new Account("b", 1000000); 

      Thread t1 = new Thread(new MoneyTransferTask(100, accA, accB), "t1"); 
      Thread t2 = new Thread(new MoneyTransferTask(100, accA, accB), "t2"); 
      Thread t3 = new Thread(new MoneyTransferTask(100, accA, accB), "t3"); 
      Thread t4 = new Thread(new MoneyTransferTask(100, accA, accB), "t4"); 
      Thread t5 = new Thread(new MoneyTransferTask(100, accA, accB), "t5"); 
      Thread t11 = new Thread(new MoneyTransferTask(100, accA, accB), "t11"); 
      Thread t12 = new Thread(new MoneyTransferTask(100, accA, accB), "t12"); 
      Thread t13 = new Thread(new MoneyTransferTask(100, accA, accB), "t13"); 
      Thread t14 = new Thread(new MoneyTransferTask(100, accA, accB), "t14"); 
      Thread t15 = new Thread(new MoneyTransferTask(100, accA, accB), "t15"); 

      Thread t6 = new Thread(new MoneyTransferTask(100, accB, accA), "t6"); 
      Thread t7 = new Thread(new MoneyTransferTask(100, accB, accA), "t7"); 
      Thread t8 = new Thread(new MoneyTransferTask(100, accB, accA), "t8"); 
      Thread t9 = new Thread(new MoneyTransferTask(100, accB, accA), "t9"); 
      Thread t10 = new Thread(new MoneyTransferTask(100, accB, accA), "t10"); 

      Thread t = new Thread(new PrintBalancesTask(accA, accB), "t"); 

      t.start(); 
      t1.start(); 
      t2.start(); 
      t3.start(); 
      t4.start(); 
      t5.start(); 
      t6.start(); 
      t7.start(); 
      t8.start(); 
      t9.start(); 
      t10.start(); 
      t11.start(); 
      t12.start(); 
      t13.start(); 
      t14.start(); 
      t15.start(); 
     } 
    } 

    class MoneyTransferTask implements Runnable { 

     int amount; 
     Account fromAccount; 
     Account toAccount; 

     public MoneyTransferTask(int amount, Account fromAccount, Account toAccount) { 
      this.amount = amount; 
      this.fromAccount = fromAccount; 
      this.toAccount = toAccount; 
     } 

     public void run() { 
      while(true) { 
       MoneyTransfer.makeTransfer(fromAccount, toAccount, amount); 
       try { 
        Thread.sleep(100); 
       }catch(InterruptedException ie) { 
        System.out.println("Thread " + Thread.currentThread().getName() + " interrupted"); 
       } 
      } 
     } 
    } 

    class PrintBalancesTask implements Runnable { 

     Account accA; 
     Account accB; 

     public PrintBalancesTask(Account accA, Account accB) { 
      this.accA = accA; 
      this.accB = accB; 
     } 

     public void run() { 
      while(true) { 

       System.out.println("AccA Balance " + accA.getBalance()); 
       System.out.println("AccB Balance " + accB.getBalance()); 

       if(accA.getBalance() + accB.getBalance() != 2000000) { 

        System.out.println("AccA Balance " + accA.getBalance()); 
        System.out.println("AccB Balance " + accB.getBalance()); 
        throw new IllegalStateException("System inconsistent"); 
       } 

       try { 
        Thread.sleep(5); 
       }catch(InterruptedException ie) { 
        System.out.println("Thread " + Thread.currentThread().getName() + " interrupted"); 
       } 
      } 
     } 

    } 

    class Account { 
     String accountId; 
     long balance; 

     Account(String accountId, long balance) { 
      this.accountId = accountId; 
      this.balance = balance; 
     } 

     synchronized long getBalance() { 
      return balance; 
     } 

     synchronized void withdraw(long amount) { 
      balance = balance - amount; 
     } 

     synchronized void deposit(long amount) { 
      balance = balance + amount; 
     } 
    } 
+0

,你能不能给我们的堆栈跟踪? –

+0

有什么不一致之处。 – Ouney

+0

您可能希望在发现不一致时让您的错误提供更多信息。 – khelwood

回答

1

你的代码应该工作得很好,问题是你的检查:

if(accA.getBalance() + accB.getBalance() != 2000000) { 

accA.getBalance()可能有些转移前进行,而accB.getBalance()将是转让后进行。

尝试增加synchronized(MoneyTransfer.class)有:

synchronized(MoneyTransfer.class) { 
    if(accA.getBalance() + accB.getBalance() != 2000000) { 
}