控制台程序。

在这个版本的银行示例中,把借款和贷款事务创建为在不同线程中执行的任务,它们把事务提交给职员。创建事务的任务是Callable<>任务,因为它们需要返回已为每个账户创建的借款或贷款事务的总额。

  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: " + ": $" + 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. synchronized(transaction.getAccount()) {
  7. int balance = 0;
  8. switch(transaction.getTransactionType()) {
  9. case CREDIT:
  10. System.out.println("Start credit of " +
  11. transaction.getAccount() + " amount: " +
  12. transaction.getAmount());
  13.  
  14. // Get current balance
  15. balance = transaction.getAccount().getBalance();
  16.  
  17. // Credits require a lot of checks...
  18. try {
  19. Thread.sleep(100);
  20.  
  21. } catch(InterruptedException e) {
  22. System.out.println(e);
  23. }
  24. balance += transaction.getAmount(); // Increment the balance
  25. transaction.getAccount().setBalance(balance); // Restore account balance
  26. System.out.println(" End credit of " +
  27. transaction.getAccount() + " amount: " +
  28. transaction.getAmount());
  29. break;
  30. case DEBIT:
  31. System.out.println("Start debit of " +
  32. transaction.getAccount() + " amount: " +
  33. transaction.getAmount());
  34.  
  35. // Get current balance
  36. balance = transaction.getAccount().getBalance();
  37.  
  38. // Debits require even more checks...
  39. try {
  40. Thread.sleep(150);
  41.  
  42. } catch(InterruptedException e) {
  43. System.out.println(e);
  44. }
  45. balance -= transaction.getAmount(); // Decrement the balance...
  46. transaction.getAccount().setBalance(balance); // Restore account balance
  47.  
  48. System.out.println(" End debit of " +
  49. transaction.getAccount() + " amount: " +
  50. transaction.getAmount());
  51. break;
  52.  
  53. default: // We should never get here
  54. System.out.println("Invalid transaction");
  55. System.exit(1);
  56. }
  57. }
  58. }
  59. }
  1. import java.util.List;
  2. import java.util.Collections;
  3. import java.util.LinkedList;
  4.  
  5. public class Clerk implements Runnable {
  6. // Constructor
  7. public Clerk(int ID, Bank theBank) {
  8. this.ID = ID;
  9. this.theBank = theBank; // Who the clerk works for
  10. }
  11.  
  12. // Receive a transaction
  13. synchronized public boolean doTransaction(Transaction transaction) {
  14. if(inTray.size() >= maxTransactions)
  15. return false;
  16. inTray.add(transaction); // Add transaction to the list
  17. return true;
  18. }
  19.  
  20. // The working clerk...
  21. public void run() {
  22. while(true) {
  23. while(inTray.size() == 0) { // No transaction waiting?
  24. try {
  25. Thread.sleep(200); // then take a break
  26. if(inTray.size() != 0) {
  27. break;
  28. } else {
  29. return;
  30. }
  31. } catch(InterruptedException e) {
  32. System.out.println("Clerk "+ ID + "\n" + e);
  33. return;
  34. }
  35. }
  36. theBank.doTransaction(inTray.remove(0));
  37. if(Thread.interrupted()) {
  38. System.out.println("Interrupt flag for Clerk " + ID + " set. Terminating.");
  39. return;
  40. }
  41. }
  42. }
  43.  
  44. int ID;
  45. private Bank theBank;
  46. private List<Transaction> inTray = // The in-tray holding transactions
  47. Collections.synchronizedList(new LinkedList<Transaction>());
  48. private int maxTransactions = 8; // Maximum transactions in the in-tray
  49. }
  1. // Generates transactions for clerks
  2. import java.util.Random;
  3. import java.util.Vector;
  4. import java.util.concurrent.Callable;
  5.  
  6. public class TransactionSource implements Callable<int[]> {
  7.  
  8. public TransactionSource(TransactionType type, int maxTrans, Vector<Account> accounts, Vector<Clerk> clerks) {
  9. this.type = type;
  10. this.maxTrans = maxTrans;
  11. this.accounts = accounts;
  12. this.clerks = clerks;
  13. totals = new int[accounts.size()];
  14. }
  15.  
  16. // The source of transactions
  17. public int[] call() {
  18. // Create transactions randomly distributed between the accounts
  19. Random rand = new Random();
  20. Transaction transaction = null; // Stores a transaction
  21. int amount = 0; // Stores an amount of money
  22. int select = 0; // Selects an account
  23. boolean done = false;
  24. for(int i = 1 ; i <= maxTrans ; ++i) {
  25. // Generate a random account index for operation
  26. select = rand.nextInt(accounts.size());
  27. amount = 50 + rand.nextInt(26); // Generate amount of $50 to $75
  28. transaction = new Transaction(accounts.get(select), // Account
  29. type, // Transaction type
  30. amount); // of amount
  31. totals[select] += amount; // Keep total tally for account
  32. done = false;
  33. while(true) {
  34. // Find a clerk to do the transaction
  35. for(Clerk clerk : clerks) {
  36. if(done = clerk.doTransaction(transaction))
  37. break;
  38. }
  39. if(done) {
  40. break;
  41. }
  42.  
  43. // No clerk was free so wait a while
  44. try {
  45. Thread.sleep(10);
  46. } catch(InterruptedException e) {
  47. System.out.println(" TransactionSource\n" + e);
  48. return totals;
  49. }
  50. }
  51. if(Thread.interrupted()) {
  52. System.out.println("Interrupt flag for "+ type + " transaction source set. Terminating.");
  53. return totals;
  54. }
  55. }
  56. return totals;
  57. }
  58.  
  59. private TransactionType type;
  60. private int maxTrans;
  61. private Vector<Account> accounts;
  62. private Vector<Clerk> clerks;
  63. private int[] totals;
  64. }
  1. import java.util.Vector;
  2. import java.util.concurrent.Executors;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Future;
  5. import java.util.concurrent.ExecutionException;
  6. import java.util.concurrent.TimeUnit;
  7.  
  8. public class UsingExecutors {
  9.  
  10. public static void main(String[] args) {
  11. int[] initialBalance = {500, 800}; // The initial account balances
  12. int[] totalCredits = new int[initialBalance.length]; // Two different cr totals
  13. int[] totalDebits = new int[initialBalance.length]; // Two different db totals
  14. int transactionCount = 20; // Number of debits and of credits
  15. int clerkCount = 2;
  16.  
  17. // Create the account, the bank, and the clerks...
  18. Bank theBank = new Bank(); // Create a bank
  19. Vector<Clerk> clerks = new Vector<Clerk>(); // Stores the clerk
  20. Vector<Account> accounts = new Vector<Account>(); // Stores the accounts
  21.  
  22. for(int i = 0 ; i < clerkCount ; ++i) {
  23. clerks.add(new Clerk(i+1, theBank)); // Create the clerks
  24. }
  25.  
  26. for(int i = 0 ; i < initialBalance.length; ++i) {
  27. accounts.add(new Account(i+1, initialBalance[i])); // Create accounts
  28. totalCredits[i] = totalDebits[i] = 0;
  29. }
  30.  
  31. ExecutorService threadPool = Executors.newCachedThreadPool();
  32.  
  33. // Create and start the transaction source threads
  34. Future<int[]> credits = threadPool.submit(new TransactionSource(TransactionType.CREDIT, transactionCount, accounts, clerks));
  35. Future<int[]> debits = threadPool.submit(new TransactionSource(TransactionType.DEBIT, transactionCount, accounts, clerks));
  36.  
  37. // Create and start the clerk threads
  38. for(Clerk clerk : clerks) {
  39. threadPool.submit(clerk);
  40. }
  41. try {
  42. totalCredits = credits.get();
  43. totalDebits = debits.get();
  44. } catch(ExecutionException e) {
  45. System.out.println(e.getCause());
  46. } catch(InterruptedException e) {
  47. System.out.println(e);
  48. }
  49.  
  50. // Orderly shutdown when all threads have ended
  51. threadPool.shutdown();
  52. try {
  53. threadPool.awaitTermination(10L, TimeUnit.SECONDS);
  54. } catch(InterruptedException e) {
  55. System.out.println(e);
  56. }
  57.  
  58. if(threadPool.isTerminated()) {
  59. System.out.println("\nAll clerks have completed their tasks.\n");
  60. } else {
  61. System.out.println("\nClerks still running - shutting down anyway.\n");
  62. threadPool.shutdownNow();
  63. }
  64.  
  65. // Now output the results
  66. for(int i = 0 ; i < accounts.size() ; ++i) {
  67. System.out.println("Account Number:"+accounts.get(i).getAccountNumber()+"\n"+
  68. "Original balance : $" + initialBalance[i] + "\n" +
  69. "Total credits : $" + totalCredits[i] + "\n" +
  70. "Total debits : $" + totalDebits[i] + "\n" +
  71. "Final balance : $" + accounts.get(i).getBalance() + "\n" +
  72. "Should be : $" + (initialBalance[i]
  73. + totalCredits[i]
  74. - totalDebits[i]) + "\n");
  75. }
  76. }
  77. }

Java基础之线程——使用执行器(UsingExecutors)的更多相关文章

  1. Java基础-多线程-③线程同步之synchronized

    使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...

  2. 【Java基础】线程和并发机制

    前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...

  3. Java基础篇——线程、并发编程知识点全面介绍(面试、学习的必备索引)

    原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10739579.html,希望大家多多支持!!! 一.线程基础 1.线程与进程 线程是指进程 ...

  4. Java基础_线程的使用及创建线程的三种方法

    线程:线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 进程:进 ...

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

    控制台程序. 当两个或多个线程共享同一资源时,例如文件或内存块,就需要采取措施,确保其中的一个线程不会修改另一个线程正在使用的资源.当其中的一个线程更新文件中的某个记录,同时另一个线程正在检索这个记录 ...

  6. Java基础之线程——使用Runnable接口(JumbleNames)

    控制台程序. 除了定义Thread新的子类外,还可以在类中实现Runnable接口.您会发现这比从Thread类派生子类更方便,因为在实现Runnable接口时可以从不是Thread的类派生子类,并且 ...

  7. Java基础之线程——派生自Thread类的子类(TryThread)

    控制台程序. 程序总是至少有一个线程,程序开始执行时就会创建这个线程.在普通的Java应用程序中,这个线程从mian()方法的开头启动. 要开始执行线程,可以调用Thread对象的start()方法. ...

  8. Java基础8-多线程;同步代码块

    作业解析 利用白富美接口案例,土豪征婚使用匿名内部类对象实现. interface White{ public void white(); } interface Rich{ public void ...

  9. Java基础-多线程-①线程的创建和启动

    简单阐释进程和线程 对于进程最直观的感受应该就是“windows任务管理器”中的进程管理: (计算机原理课上的记忆已经快要模糊了,简单理解一下):一个进程就是一个“执行中的程序”,是程序在计算机上的一 ...

随机推荐

  1. coursera-miniproject stopwatch任务总结

    ---恢复内容开始--- 首先是miniproject的说明: combin text drawing in canvas with time to build digital stopwatch. ...

  2. mysql中文字段转拼音首字母,以及中文拼音模糊查询

    创建存储过程,将中文字段转拼音首字母 CREATE DEFINER=`root`@`%` FUNCTION `fristPinyin`(P_NAME VARCHAR(255)) RETURNS var ...

  3. 区分总结innerHeight与clientHeight、innerWidth与clientWidth、scrollLeft与pageXOffset等属性

    window对象: (1)innerHeight属性:窗口中文档显示区域的高度,不包括菜单栏.工具栏等部分.该属性可读可写. IE不支持该属性,IE中body元素的clientHeight属性与该属性 ...

  4. os相关方法总结

    __file__表示当前文件 os.path.dirname表示当前文件所在路径的父路径 os.pardir表示当前文件名 os.path.join表示合并 os.path.abspath表示绝对路径

  5. Hbase中rowkey设计原则

    1.热点问题 在某一时间段,有大量的数据同时对一个region进行操作 2.原因 对rowkey的设计不合理 对rowkey的划分不合理 3.解决方式 rowkey是hbase的读写唯一标识 最大长度 ...

  6. 修改delphi xe6 FMX Label字体颜色

    delphi fmx的字体等设置默认与皮肤有关,用代码直接修改字体颜色等是无效的,如何才能用代码修改呢?请按以下方法就可以: 1.在Object inspector中取消StlyedSettings中 ...

  7. gradlew常用命令

    ./gradlew -v 查看版本 ./gradlew clean 清理.下载依赖 ./gradlew build  构建 libgdx项目中的gradlew run: ./gradlew deskt ...

  8. LINQ之select方法选择多个字段

    单个字段: var list1 = list.Select(field1 => field1.CouponID).ToList(); 多个字段: var list1 = list.Select( ...

  9. 在zendstudio中添加注释

    /** * * * @access public * @param string $cat_id 分类查询字符串 * @return string */ 然后在function之前的一行打上/**然后 ...

  10. imx6 uboot lcd

    本文记录imx6 uboot中关于lcd初始化的过程. uboot中相关的文件: cpu/arm_cortexa8/start.S lib_arm/board.c board/freescale/mx ...