• Java基础之线程——管理线程同步方法(BankOperation2)


    控制台程序。

    当两个或多个线程共享同一资源时,例如文件或内存块,就需要采取措施,确保其中的一个线程不会修改另一个线程正在使用的资源。当其中的一个线程更新文件中的某个记录,同时另一个线程正在检索这个记录,就会出现灾难性的结果。管理这种情形的一种方式是对涉及的线程使用同步机制。

    同步的目标是当多个线程希望访问同一资源时,确保在任意时刻只有一个线程可以访问。使用同步机制可以通过两种方式管理线程的执行:

    1、可以在方法级别管理代码,这涉及方法的同步。

    2、可以在块级别管理代码,这使用块的同步。

    同步方法可以使任意类中方法的子集(或者所有的方法)都是互斥的,在任意时刻都只能执行其中的一个方法。使用synchronized关键字声明类中的方法,就可以把它们设置为互斥的。

     1 // Define the bank
     2 
     3 public class Bank {
     4   // Perform a transaction
     5   synchronized public void doTransaction(Transaction transaction) {
     6     int balance = transaction.getAccount().getBalance();               // Get current balance
     7 
     8     switch(transaction.getTransactionType()) {
     9       case CREDIT:
    10         // Credits require a lot of checks...
    11         try {
    12           Thread.sleep(100);
    13 
    14         } catch(InterruptedException e) {
    15           System.out.println(e);
    16         }
    17         balance += transaction.getAmount();                            // Increment the balance
    18         break;
    19 
    20       case DEBIT:
    21         // Debits require even more checks...
    22         try {
    23           Thread.sleep(150);
    24 
    25         } catch(InterruptedException e) {
    26           System.out.println(e);
    27         }
    28         balance -= transaction.getAmount();                            // Decrement the balance
    29         break;
    30 
    31       default:                                                         // We should never get here
    32         System.out.println("Invalid transaction");
    33         System.exit(1);
    34    }
    35     transaction.getAccount().setBalance(balance);                      // Restore the account balance
    36   }
    37 }
     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 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 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 import java.util.Random;
     2 
     3 public class BankOperation2 {
     4   public static void main(String[] args) {
     5     int initialBalance = 500;                                          // The initial account balance
     6     int totalCredits = 0;                                              // Total credits on the account
     7     int totalDebits =0;                                                // Total debits on the account
     8     int transactionCount = 20;                                         // Number of debits and 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     Account account = new Account(1, initialBalance);                  // Create an account
    15 
    16     // Create the threads for the clerks as daemon, and start them off
    17     Thread clerk1Thread = new Thread(clerk1);
    18     Thread clerk2Thread = new Thread(clerk2);
    19     clerk1Thread.setDaemon(true);                                      // Set first as daemon
    20     clerk2Thread.setDaemon(true);                                      // Set second as daemon
    21     clerk1Thread.start();                                              // Start the first
    22     clerk2Thread.start();                                              // Start the second
    23 
    24     // Generate transactions of each type and pass to the clerks
    25     Random rand = new Random();                                        // Random number generator
    26     Transaction transaction;                                           // Stores a transaction
    27     int amount = 0;                                                    // stores an amount of money
    28     for(int i = 1 ; i <= transactionCount ; ++i) {
    29       amount = 50 + rand.nextInt(26);                                  // Generate amount of $50 to $75
    30       transaction = new Transaction(account,                           // Account
    31                               TransactionType.CREDIT,                  // Credit transaction
    32                                     amount);                           //  of amount
    33       totalCredits += amount;                                          // Keep total credit tally
    34 
    35       // Wait until the first clerk is free
    36       while(clerk1.isBusy()) {
    37         try {
    38           Thread.sleep(25);                                            // Busy so try later
    39 
    40         } catch(InterruptedException e) {
    41           System.out.println(e);
    42         }
    43       }
    44       clerk1.doTransaction(transaction);                               // Now do the credit
    45 
    46       amount = 30 + rand.nextInt(31);                                  // Generate amount of $30 to $60
    47       transaction = new Transaction(account,                           // Account
    48                                TransactionType.DEBIT,                  // Debit transaction
    49                                     amount);                           //  of amount
    50       totalDebits += amount;                                           // Keep total debit tally
    51       // Wait until the second clerk is free
    52       while(clerk2.isBusy()) {
    53         try {
    54           Thread.sleep(25);                                            // Busy so try later
    55 
    56         } catch(InterruptedException e) {
    57           System.out.println(e);
    58         }
    59       }
    60       clerk2.doTransaction(transaction);                               // Now do the debit
    61     }
    62 
    63     // Wait until both clerks are done
    64     while(clerk1.isBusy() || clerk2.isBusy()) {
    65       try {
    66         Thread.sleep(25);
    67 
    68       } catch(InterruptedException e) {
    69         System.out.println(e);
    70       }
    71     }
    72 
    73     // Now output the results
    74     System.out.println(
    75               "Original balance : $" + initialBalance+"
    " +
    76               "Total credits    : $" + totalCredits+"
    " +
    77               "Total debits     : $" + totalDebits+"
    " +
    78               "Final balance    : $" + account.getBalance() + "
    " +
    79               "Should be        : $" + (initialBalance + totalCredits - totalDebits));
    80   }
    81 }


    把处理账户的方法声明为synchronized,在其中一个职员对账户调用方法时,禁止另一个职员也调用同一个方法。

    目前存在的问题是:银行的效率非常低,当其中一个职员在处理事物时,另一个职员却在闲着。

  • 相关阅读:
    Github使用手册2——Github使用自己的远程仓库
    GitHub使用手册1——fork and pull request
    如何申请Pycharm学生免费激活码
    博客园入园手册2——Markdown编辑器1
    博客园入园手册1——TinyMEC编辑器
    实验一 GIT 代码版本管理
    结对项目-数独程序扩展(要求细化更新)
    个人作业Week2-代码复审(修改明确了要求)
    个人作业-Week1(新增详细说明)
    个人项目-数独
  • 原文地址:https://www.cnblogs.com/mannixiang/p/3446734.html
Copyright © 2020-2023  润新知