Java 2 入门经典(线程、线程同步示例代码)

<<Java 2 入门经典>>(Ivor Horton's Beginning Java 2,JDK5 Edition)
第16章线程
1.继承Thread
import java.io.IOException;

public class TryThread extends Thread {
public TryThread(String firstName, String secondName, long delay) {
    this.firstName = firstName;      // Store the first name
    this.secondName = secondName;    // Store the second name
    aWhile = delay;                  // Store the delay
    setDaemon(true);                 // Thread is daemon
}

public static void main(String[] args) {
    // Create three threads
    Thread first = new TryThread("张 ", "三 ", 200L);
    Thread second = new TryThread("李 ", "四 ", 300L);
    Thread third = new TryThread("王 ", "五 ", 500L);

    System.out.println("Press Enter when you have had enough.../n");
    first.start();                      // Start the first thread
    second.start();                     // Start the second thread
    //third.setDaemon(false);
    third.start();                      // Start the third thread

    try {
      System.in.read();                 // Wait until Enter key pressed
      System.out.println("Enter pressed.../n");

    } catch (IOException e) {           // Handle IO exception
      System.out.println(e);            // Output the exception
    }
    System.out.println("Ending main()");
    return;
}

// Method where thread execution will start
public void run() {
    try {
      while(true) {                          // Loop indefinitely...
        System.out.print(firstName);         // Output first name
        sleep(aWhile);                       // Wait aWhile msec.
        System.out.print(secondName + "/n"); // Output second name
      }
    } catch(InterruptedException e) {        // Handle thread interruption
      System.out.println(firstName + secondName + e);     // Output the exception
    }
}

private String firstName;          // Store for first name
private String secondName;         // Store for second name
private long aWhile;               // Delay in milliseconds
}
使用setDaemon(true);设置为守护线程,则当创建它们的纯种结束后守护线程都会灭亡,即main()结束后first,second,third三个Thread
都会死亡。
2.使用Runnable接口
package Ch16;

import java.io.IOException;

public class JumbleNames implements Runnable {
// Constructor
public JumbleNames(String firstName, String secondName, long delay) {
    this.firstName = firstName;                     // Store the first name
    this.secondName = secondName;                   // Store the second name
    aWhile = delay;                                 // Store the delay
}

// Method where thread execution will start
public void run() {
    try {
      while(true) {                                 // Loop indefinitely...
        System.out.print(firstName);                // Output first name
        Thread.sleep(aWhile);                       // Wait aWhile msec.
        System.out.print(secondName+"/n");          // Output second name
      }
    } catch(InterruptedException e) {               // Handle thread interruption
      System.out.println(firstName + secondName + e);     // Output the exception
    }
}

public static void main(String[] args) {
    // Create three threads
    Thread first = new Thread(new JumbleNames("张 ", "三 ", 200L));
    Thread second = new Thread(new JumbleNames("李 ", "四 ", 300L));
    Thread third = new Thread(new JumbleNames("王 ", "五 ", 500L));

    // Set threads as daemon
    first.setDaemon(true);
    second.setDaemon(true);
    third.setDaemon(true);
    System.out.println("Press Enter when you have had enough.../n");
    first.start();                                 // Start the first thread
    second.start();                                // Start the second thread
    third.start();                                 // Start the third thread
    try {
      System.in.read();                            // Wait until Enter key pressed
      System.out.println("Enter pressed.../n");

    } catch (IOException e) {                      // Handle IO exception
      System.out.println(e);                       // Output the exception
    }
    System.out.println("Ending main()");
    return;
}

private String firstName;                         // Store for first name
private String secondName;                        // Store for second name
private long aWhile;                              // Delay in milliseconds
}

3.线程同步 (银行的例子)
使用synchronized声明使方法间互斥,一个类对象的所有同步方法中,一次只能有一个可以执行。
注意这只是控制同一个对象的并发访问,对并行执行同一类的两个不同对象的同步方法并没有控制。

Bank类表示银行计算机
Account类表示帐户
Transaction类表示操作(存或取款)
Clerk表示职员(保存了银行信息和当前业务的细节,各职员独立操作,负责和银行通信来初始化账户的存或取款业务,线程).
//Bank表示银行的计算机,是账户执行操作的代理//
public class Bank {
// Perform a transaction
//public void doTransaction(Transaction transaction) { //会有问题
synchronized public void doTransaction(Transaction transaction) {
    int balance = transaction.getAccount().getBalance();   // Get current balance

    switch(transaction.getTransactionType()) {
      case Transaction.CREDIT:
        // Credits require a lot of checks...
        try {
          Thread.sleep(100);

        } catch(InterruptedException e) {
          System.out.println(e);
        }
        balance += transaction.getAmount();         // Increment the balance
        break;

      case Transaction.DEBIT:
        // Debits require even more checks...
        try {
          Thread.sleep(150);

        } catch(InterruptedException e) {
          System.out.println(e);
        }
        balance -= transaction.getAmount();         // Decrement the balance
        break;

      default:                                      // We should never get here
        System.out.println("Invalid transaction");
        System.exit(1);
   }
    transaction.getAccount().setBalance(balance);   // Restore the account balance
}
}
Transaction /
public class Transaction {
// Transaction types
public static final int DEBIT = 0;
public static final int CREDIT = 1;
public static String[] types = {"Debit","Credit"};

// Constructor
public Transaction(Account account, int transactionType, int amount) {
    this.account = account;
    this.transactionType = transactionType;
    this.amount = amount;
}

public Account getAccount() {
    return account;
}

public int getTransactionType() {
    return transactionType;
}

public int getAmount() {
    return amount;
}

public String toString() {
    return types[transactionType] + " A//C: " + ": $" + amount;
}

private Account account;
private int amount;
private int transactionType;
}
///Account /
public class Account {
// Constructor
public Account(int accountNumber, int balance) {
    this.accountNumber = accountNumber;            // Set the account number
    this.balance = balance;                        // Set the initial balance
}

// Return the current balance
public int getBalance() {
    return balance;
}

// Set the current balance
public void setBalance(int balance) {
    this.balance = balance;
}

public int getAccountNumber() {
    return accountNumber;
}

public String toString() {
    return "A//C No. "+accountNumber+" : $"+balance;
}

private int balance;                             // The current account balance
private int accountNumber;                       // Identifies this account
}
//Clerk /
//Clerk表示职员,保存了银行信息和当前业务的细节,各职员独立操作,负责和银行通信来初始化账户的存或取款业务,线程).
public class Clerk implements Runnable {
// Constructor
public Clerk(Bank theBank) {
    this.theBank = theBank;           // Who the clerk works for
    inTray = null;                    // No transaction initially
}

// Receive a transaction
public void doTransaction(Transaction transaction) {
    inTray = transaction;
}

// The working clerk...
public void run() {
    while(true) {
      while(inTray == null) {         // No transaction waiting?
        try {
          Thread.sleep(150);          // Then take a break...

        } catch(InterruptedException e) {
          System.out.println(e);
        }
      }

      theBank.doTransaction(inTray);
      inTray = null;                  // In-tray is empty
    }
}

// Busy check
public boolean isBusy() {
    return inTray != null;            // A full in-tray means busy!
}

private Bank theBank;               // The employer - an electronic marvel
private Transaction inTray;         // The in-tray holding a transaction,业务箱
}
//BankOperation
//只有一个帐号,两个职员
import java.util.Random;
public class BankOperation {
public static void main(String[] args) {
    int initialBalance = 500;                          // The initial account balance
    int totalCredits = 0;                              // Total credits on the account
    int totalDebits =0;                                // Total debits on the account
    int transactionCount = 20;                         // Number of debits and credits

    // Create the account, the bank, and the clerks...
    Bank theBank = new Bank();                         // Create a bank
    Clerk clerk1 = new Clerk(theBank);                 // Create the first clerk
    Clerk clerk2 = new Clerk(theBank);                 // Create the second clerk
    Account account = new Account(1, initialBalance); // Create an account

    // Create the threads for the clerks as daemon, and start them off
    Thread clerk1Thread = new Thread(clerk1);
    Thread clerk2Thread = new Thread(clerk2);
    clerk1Thread.setDaemon(true);                      // Set first as daemon
    clerk2Thread.setDaemon(true);                      // Set second as daemon
    clerk1Thread.start();                              // Start the first
    clerk2Thread.start();                              // Start the second

    // Generate transactions of each type and pass to the clerks
    Random rand = new Random();                        // Random number generator
    Transaction transaction;                           // Stores a transaction
    int amount = 0;                                    // stores an amount of money
    for(int i = 1; i <= transactionCount; i++) {
      amount = 50 + rand.nextInt(26);                  // Generate amount of $50 to $75
      transaction = new Transaction(account,           // Account
                                    Transaction.CREDIT,// Credit transaction
                                    amount);           // of amount
      totalCredits += amount;                          // Keep total credit tally

      // Wait until the first clerk is free
      while(clerk1.isBusy()) {
        try {
          Thread.sleep(25);                            // Busy so try later

        } catch(InterruptedException e) {
          System.out.println(e);
        }
      }
      clerk1.doTransaction(transaction);             // Now do the credit

      amount = 30 + rand.nextInt(31);                // Generate amount of $30 to $60
      transaction = new Transaction(account,            // Account
                                    Transaction.DEBIT, // Debit transaction
                                    amount);            // of amount
      totalDebits += amount;                         // Keep total debit tally
      // Wait until the second clerk is free
      while(clerk2.isBusy()) {
        try {
          Thread.sleep(25);                            // Busy so try later

        } catch(InterruptedException e) {
          System.out.println(e);
        }
      }
      clerk2.doTransaction(transaction);             // Now do the debit
    }//end for

    // Wait until both clerks are done
    while(clerk1.isBusy() || clerk2.isBusy()) {
      try {
        Thread.sleep(25);

      } catch(InterruptedException e) {
        System.out.println(e);
      }
    }

    // Now output the results
    System.out.println(
              "Original balance : $" + initialBalance+"/n" +
              "Total credits    : $" + totalCredits+"/n" +
              "Total debits     : $" + totalDebits+"/n" +
              "Final balance    : $" + account.getBalance() + "/n" +
              "Should be        : $" + (initialBalance + totalCredits - totalDebits));
}
}

/// 两个帐户,两个职员
public class BankOperation {
public static void main(String[] args) {
    int[] initialBalance = {500, 800};                 // The initial account balances
    int[] totalCredits = new int[initialBalance.length]; //Two different cr totals
    int[] totalDebits = new int[initialBalance.length]; //Two different db totals
    int transactionCount = 20;                         // Number of debits and credits

    // Create the bank and the clerks...
    Bank theBank = new Bank();                         // Create a bank
    Clerk clerk1 = new Clerk(theBank);                 // Create the first clerk
    Clerk clerk2 = new Clerk(theBank);                 // Create the second clerk

    // Create the accounts, and initialize total credits and debits
    Account[] accounts = new Account[initialBalance.length];
    for(int i = 0; i < initialBalance.length; i++) {
      accounts[i] = new Account(i+1, initialBalance[i]); // Create accounts
      totalCredits[i] = totalDebits[i] = 0;
    }

    // Create the threads for the clerks as daemon, and start them off
    Thread clerk1Thread = new Thread(clerk1);
    Thread clerk2Thread = new Thread(clerk2);
    clerk1Thread.setDaemon(true);                      // Set first as daemon
    clerk2Thread.setDaemon(true);                      // Set second as daemon
    clerk1Thread.start();                              // Start the first
    clerk2Thread.start();                              // Start the second

    // Create transactions randomly distributed between the accounts
    Random rand = new Random();
    Transaction transaction;                         // Stores a transaction
    int amount = 0;                                  // Stores an amount of money
    int select = 0;                                  // Selects an account
    for(int i = 1; i <= transactionCount; i++) {
      // Choose an account at random for credit operation
      select = rand.nextInt(accounts.length);
      amount = 50 + rand.nextInt(26);                // Generate amount of $50 to $75
      transaction = new Transaction(accounts[select],       // Account
                                        Transaction.CREDIT, // Credit transaction
                                        amount);            // of amount
      totalCredits[select] += amount;                // Keep total credit tally

      // Wait until the first clerk is free
      while(clerk1.isBusy()) {
        try {
          Thread.sleep(25);                            // Busy so try later
        } catch(InterruptedException e) {
          System.out.println(e);
        }
      }
      clerk1.doTransaction(transaction);             // Now do the credit

      // choose an account at random for debit operation
      select = rand.nextInt(accounts.length);
      amount = 30 + rand.nextInt(31);                // Generate amount of $30 to $60
      transaction = new Transaction(accounts[select],   // Account
                                    Transaction.DEBIT, // Debit transaction
                                    amount);            // of amount
      totalDebits[select] += amount;                 // Keep total debit tally

      // Wait until the second clerk is free
      while(clerk2.isBusy()) {
        try {
          Thread.sleep(25);                         // Busy so try later
        } catch(InterruptedException e) {
          System.out.println(e);
        }
      }
      clerk2.doTransaction(transaction);             // Now do the debit
    }
   
    // Wait until both clerks are done
    while(clerk1.isBusy() || clerk2.isBusy()) {
      try {
        Thread.sleep(25);

      } catch(InterruptedException e) {
        System.out.println(e);
      }
    }

    // Now output the results
    for(int i = 0; i < accounts.length; i++) {  
      System.out.println("Account Number:"+accounts[i].getAccountNumber()+"/n"+
         "Original balance    : $" + initialBalance[i] + "/n" +
         "Total credits       : $" + totalCredits[i] + "/n" +
         "Total debits        : $" + totalDebits[i] + "/n" +
         "Final balance       : $" + accounts[i].getBalance() + "/n" +
         "Should be           : $" + (initialBalance[i]
                                   + totalCredits[i]
                                   - totalDebits[i]) + "/n");
    }
}
}

///类Bank声明为synchronized严重限制了程序。如果一种操作在进行则其他的操作都不能进行,
//实际上,一个账户在进行业务时,不该阻止另一个账户上的业务操作,对Bank进行修改

synchronized(transaction.getAccount()) {
          System.out.println("Start credit of " +
                  transaction.getAccount() + " amount: " +
                  transaction.getAmount());

          // Get current balance
          int balance = transaction.getAccount().getBalance();

         ....
          balance += transaction.getAmount();           // Increment the balance
       ....
          transaction.getAccount().setBalance(balance); // Restore the account balance
          break;
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值