zoukankan      html  css  js  c++  java
  • Java基础之线程——管理线程同步代码块(BankOperation4)

    控制台程序。

    除了同步类对象的方法之外,还可以把程序中的语句或代码块制定为synchronized,这种方式更强大,因为可以指定哪个对象从语句或代码块的同步中获益,而不像同步方法那样仅仅是包含代码的对象能获益。这里可以对给定代码块的任何对象设置锁。当对给定对象执行同步的代码块时,就不能执行对相同对象同步的其他代码或方法。

     1 // Defines a customer account
     2 public class Account {
     3   // Constructor
     4   public Account(int accountNumber, int balance) {
     5     this.accountNumber = accountNumber;                                // Set the account number
     6     this.balance = balance;                                            // Set the initial balance
     7   }
     8 
     9   // Return the current balance
    10   public int getBalance() {
    11     return balance;
    12   }
    13 
    14   // Set the current balance
    15   public void setBalance(int balance) {
    16     this.balance = balance;
    17   }
    18 
    19   public int getAccountNumber() {
    20     return accountNumber;
    21   }
    22 
    23   @Override
    24   public String toString() {
    25     return "A/C No. " + accountNumber + " : $" + balance;
    26   }
    27 
    28   private int balance;                                                 // The current account balance
    29   private int accountNumber;                                           // Identifies this account
    30 }
    1 // Bank account transaction types
    2 public enum TransactionType {DEBIT, CREDIT }
     1 public class Transaction {
     2   // Constructor
     3   public Transaction(Account account, TransactionType type, int amount) {
     4     this.account = account;
     5     this.type = type;
     6     this.amount = amount;
     7   }
     8 
     9   public Account getAccount() {
    10     return account;
    11   }
    12 
    13   public TransactionType getTransactionType() {
    14     return type;
    15   }
    16 
    17   public int getAmount() {
    18     return amount;
    19   }
    20   @Override
    21   public String toString() {
    22     return type + " A//C: " + account + ": $" + amount;
    23   }
    24 
    25   private Account account;
    26   private int amount;
    27   private TransactionType type;
    28 }
     1 // Define the bank
     2 
     3 public class Bank {
     4   // Perform a transaction
     5   public void doTransaction(Transaction transaction) {
     6     switch(transaction.getTransactionType()) {
     7       case CREDIT:
     8         synchronized(transaction.getAccount()) {
     9         System.out.println("Start credit of " +
    10                 transaction.getAccount() + " amount: " +
    11                 transaction.getAmount());
    12 
    13           // Get current balance
    14           int balance = transaction.getAccount().getBalance();
    15 
    16           // Credits require a lot of checks...
    17           try {
    18             Thread.sleep(100);
    19 
    20           } catch(InterruptedException e) {
    21             System.out.println(e);
    22           }
    23           balance += transaction.getAmount();                          // Increment the balance
    24           transaction.getAccount().setBalance(balance);                // Restore account balance
    25           System.out.println("  End credit of " +
    26                   transaction.getAccount() + " amount: " +
    27                   transaction.getAmount());
    28           break;
    29         }
    30       case DEBIT:
    31         synchronized(transaction.getAccount()) {
    32           System.out.println("Start debit of " +
    33                   transaction.getAccount() + " amount: " +
    34                   transaction.getAmount());
    35 
    36           // Get current balance
    37           int balance = transaction.getAccount().getBalance();
    38 
    39           // Debits require even more checks...
    40           try {
    41             Thread.sleep(150);
    42 
    43           } catch(InterruptedException e) {
    44             System.out.println(e);
    45           }
    46           balance -= transaction.getAmount();                          // Decrement the balance...
    47           transaction.getAccount().setBalance(balance);                // Restore account balance
    48 
    49           System.out.println("  End debit of " +
    50                   transaction.getAccount() + " amount: " +
    51                   transaction.getAmount());
    52           break;
    53         }
    54 
    55       default:                                                         // We should never get here
    56         System.out.println("Invalid transaction");
    57         System.exit(1);
    58     }
    59   }
    60 }
     1 public class Clerk implements Runnable {
     2   // Constructor
     3   public Clerk(Bank theBank) {
     4     this.theBank = theBank;                                            // Who the clerk works for
     5     inTray = null;                                                     // No transaction initially
     6   }
     7 
     8   // Receive a transaction
     9   public void doTransaction(Transaction transaction) {
    10     inTray = transaction;
    11   }
    12 
    13   // The working clerk...
    14   public void run() {
    15     while(true) {                                                      // Non-stop work...
    16       while(inTray == null) {                                          // No transaction waiting?
    17         try {
    18           Thread.sleep(150);                                           // Then take a break...
    19 
    20         } catch(InterruptedException e) {
    21           System.out.println(e);
    22         }
    23       }
    24 
    25       theBank.doTransaction(inTray);
    26       inTray = null;                                                   // In-tray is empty
    27     }
    28   }
    29 
    30   // Busy check
    31   public boolean isBusy() {
    32     return inTray != null;                                             // A full in-tray means busy!
    33   }
    34 
    35   private Bank theBank;                                                // The employer - an electronic marvel
    36   private Transaction inTray;                                          // The in-tray holding a transaction
    37 }
     1 import java.util.Random;
     2 
     3 public class BankOperation4 {
     4   public static void main(String[] args) {
     5     int[] initialBalance = {500, 800};                                 // The initial account balances
     6     int[] totalCredits = new int[initialBalance.length];               // Two different cr totals
     7     int[] totalDebits = new int[initialBalance.length];                // Two different db totals
     8     int transactionCount = 20;                                         // Number of debits and of credits
     9 
    10     // Create the account, the bank, and the clerks...
    11     Bank theBank = new Bank();                                         // Create a bank
    12     Clerk clerk1 = new Clerk(theBank);                                 // Create the first clerk
    13     Clerk clerk2 = new Clerk(theBank);                                 // Create the second clerk
    14 
    15     // Create the accounts, and initialize total credits and debits
    16     Account[] accounts = new Account[initialBalance.length];
    17     for(int i = 0 ; i < initialBalance.length ; ++i) {
    18       accounts[i] = new Account(i+1, initialBalance[i]);               // Create accounts
    19       totalCredits[i] = totalDebits[i] = 0;
    20     }
    21     // Create the threads for the clerks as daemon, and start them off
    22     Thread clerk1Thread = new Thread(clerk1);
    23     Thread clerk2Thread = new Thread(clerk2);
    24     clerk1Thread.setDaemon(true);                                      // Set first as daemon
    25     clerk2Thread.setDaemon(true);                                      // Set second as daemon
    26     clerk1Thread.start();                                              // Start the first
    27     clerk2Thread.start();                                              // Start the second
    28 
    29     // Create transactions randomly distributed between the accounts
    30     Random rand = new Random();
    31     Transaction transaction;                                           // Stores a transaction
    32     int amount = 0;                                                    // Stores an amount of money
    33     int select = 0;                                                    // Selects an account
    34     for(int i = 1; i <= transactionCount; i++) {
    35       // Choose an account at random for credit operation
    36       select = rand.nextInt(accounts.length);
    37       amount = 50 + rand.nextInt(26);                                  // Generate amount of $50 to $75
    38       transaction = new Transaction(accounts[select],                  // Account
    39                               TransactionType.CREDIT,                  // Credit transaction
    40                                     amount);                           //  of amount
    41       totalCredits[select] += amount;                                  // Keep total credit tally
    42 
    43       // Wait until the first clerk is free
    44       while(clerk1.isBusy()) {
    45         try {
    46           Thread.sleep(25);                                            // Busy so try later
    47         } catch(InterruptedException e) {
    48           System.out.println(e);
    49         }
    50       }
    51       clerk1.doTransaction(transaction);                               // Now do the credit
    52 
    53       // choose an account at random for debit operation
    54       select = rand.nextInt(accounts.length);
    55       amount = 30 + rand.nextInt(31);                                  // Generate amount of $30 to $60
    56       transaction = new Transaction(accounts[select],                  // Account
    57                               TransactionType.DEBIT,                   // Debit transaction
    58                                     amount);                           //  of amount
    59       totalDebits[select] += amount;                                   // Keep total debit tally
    60 
    61       // Wait until the second clerk is free
    62       while(clerk2.isBusy()) {
    63         try {
    64           Thread.sleep(25);                                            // Busy so try later
    65         } catch(InterruptedException e) {
    66           System.out.println(e);
    67         }
    68       }
    69       clerk2.doTransaction(transaction);                               // Now do the debit
    70     }
    71 
    72     // Wait until both clerks are done
    73     while(clerk1.isBusy() || clerk2.isBusy()) {
    74       try {
    75         Thread.sleep(25);
    76 
    77       } catch(InterruptedException e) {
    78         System.out.println(e);
    79       }
    80     }
    81 
    82     // Now output the results
    83     for(int i = 0; i < accounts.length; ++i) {
    84       System.out.println("Account Number:"+accounts[i].getAccountNumber()+"
    "+
    85          "Original balance    : $" + initialBalance[i] + "
    " +
    86          "Total credits       : $" + totalCredits[i] + "
    " +
    87          "Total debits        : $" + totalDebits[i] + "
    " +
    88          "Final balance       : $" + accounts[i].getBalance() + "
    " +
    89          "Should be           : $" + (initialBalance[i]
    90                                    + totalCredits[i]
    91                                    - totalDebits[i]) + "
    ");
    92     }
    93   }
    94 }

    synchronized关键字后面圆括号中的表达式用来指定要同步的对象。一旦执行到给定账户对象的同步代码块,就不能再执行为这个账户对象同步的其他代码块或方法。例如,如果用事务的getAccount()方法返回的account[1]对象来引用进行贷款处理的代码块,就不能再执行这个对象的借款处理代码块,但可以执行其他对象的借款处理代码块。

  • 相关阅读:
    Nacos安装部署文档
    mysql安装部署文档
    Postgresql数据库安装部署文档
    Sentinel安装部署文档
    Nginx安装部署手册
    golang 7. defer
    golang 6. 指针 *
    golang 5. import
    golang 4. 函数 func
    golang 3. 常量 const iota
  • 原文地址:https://www.cnblogs.com/mannixiang/p/3446782.html
Copyright © 2011-2022 走看看