Java基础之线程——使用执行器(UsingExecutors)
控制台程序。
在这个版本的银行示例中,把借款和贷款事务创建为在不同线程中执行的任务,它们把事务提交给职员。创建事务的任务是Callable<>任务,因为它们需要返回已为每个账户创建的借款或贷款事务的总额。
- // Defines a customer 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;
- }
- @Override
- public String toString() {
- return "A/C No. " + accountNumber + " : $" + balance;
- }
- private int balance; // The current account balance
- private int accountNumber; // Identifies this account
- }
- // Bank account transaction types
- public enum TransactionType {DEBIT, CREDIT }
- public class Transaction {
- // Constructor
- public Transaction(Account account, TransactionType type, int amount) {
- this.account = account;
- this.type = type;
- this.amount = amount;
- }
- public Account getAccount() {
- return account;
- }
- public TransactionType getTransactionType() {
- return type;
- }
- public int getAmount() {
- return amount;
- }
- @Override
- public String toString() {
- return type + " A//C: " + ": $" + amount;
- }
- private Account account;
- private int amount;
- private TransactionType type;
- }
- // Define the bank
- public class Bank {
- // Perform a transaction
- public void doTransaction(Transaction transaction) {
- synchronized(transaction.getAccount()) {
- int balance = 0;
- switch(transaction.getTransactionType()) {
- case CREDIT:
- System.out.println("Start credit of " +
- transaction.getAccount() + " amount: " +
- transaction.getAmount());
- // Get current balance
- balance = transaction.getAccount().getBalance();
- // Credits require a lot of checks...
- try {
- Thread.sleep(100);
- } catch(InterruptedException e) {
- System.out.println(e);
- }
- balance += transaction.getAmount(); // Increment the balance
- transaction.getAccount().setBalance(balance); // Restore account balance
- System.out.println(" End credit of " +
- transaction.getAccount() + " amount: " +
- transaction.getAmount());
- break;
- case DEBIT:
- System.out.println("Start debit of " +
- transaction.getAccount() + " amount: " +
- transaction.getAmount());
- // Get current balance
- balance = transaction.getAccount().getBalance();
- // Debits require even more checks...
- try {
- Thread.sleep(150);
- } catch(InterruptedException e) {
- System.out.println(e);
- }
- balance -= transaction.getAmount(); // Decrement the balance...
- transaction.getAccount().setBalance(balance); // Restore account balance
- System.out.println(" End debit of " +
- transaction.getAccount() + " amount: " +
- transaction.getAmount());
- break;
- default: // We should never get here
- System.out.println("Invalid transaction");
- System.exit(1);
- }
- }
- }
- }
- import java.util.List;
- import java.util.Collections;
- import java.util.LinkedList;
- public class Clerk implements Runnable {
- // Constructor
- public Clerk(int ID, Bank theBank) {
- this.ID = ID;
- this.theBank = theBank; // Who the clerk works for
- }
- // Receive a transaction
- synchronized public boolean doTransaction(Transaction transaction) {
- if(inTray.size() >= maxTransactions)
- return false;
- inTray.add(transaction); // Add transaction to the list
- return true;
- }
- // The working clerk...
- public void run() {
- while(true) {
- while(inTray.size() == 0) { // No transaction waiting?
- try {
- Thread.sleep(200); // then take a break
- if(inTray.size() != 0) {
- break;
- } else {
- return;
- }
- } catch(InterruptedException e) {
- System.out.println("Clerk "+ ID + "\n" + e);
- return;
- }
- }
- theBank.doTransaction(inTray.remove(0));
- if(Thread.interrupted()) {
- System.out.println("Interrupt flag for Clerk " + ID + " set. Terminating.");
- return;
- }
- }
- }
- int ID;
- private Bank theBank;
- private List<Transaction> inTray = // The in-tray holding transactions
- Collections.synchronizedList(new LinkedList<Transaction>());
- private int maxTransactions = 8; // Maximum transactions in the in-tray
- }
- // Generates transactions for clerks
- import java.util.Random;
- import java.util.Vector;
- import java.util.concurrent.Callable;
- public class TransactionSource implements Callable<int[]> {
- public TransactionSource(TransactionType type, int maxTrans, Vector<Account> accounts, Vector<Clerk> clerks) {
- this.type = type;
- this.maxTrans = maxTrans;
- this.accounts = accounts;
- this.clerks = clerks;
- totals = new int[accounts.size()];
- }
- // The source of transactions
- public int[] call() {
- // Create transactions randomly distributed between the accounts
- Random rand = new Random();
- Transaction transaction = null; // Stores a transaction
- int amount = 0; // Stores an amount of money
- int select = 0; // Selects an account
- boolean done = false;
- for(int i = 1 ; i <= maxTrans ; ++i) {
- // Generate a random account index for operation
- select = rand.nextInt(accounts.size());
- amount = 50 + rand.nextInt(26); // Generate amount of $50 to $75
- transaction = new Transaction(accounts.get(select), // Account
- type, // Transaction type
- amount); // of amount
- totals[select] += amount; // Keep total tally for account
- done = false;
- while(true) {
- // Find a clerk to do the transaction
- for(Clerk clerk : clerks) {
- if(done = clerk.doTransaction(transaction))
- break;
- }
- if(done) {
- break;
- }
- // No clerk was free so wait a while
- try {
- Thread.sleep(10);
- } catch(InterruptedException e) {
- System.out.println(" TransactionSource\n" + e);
- return totals;
- }
- }
- if(Thread.interrupted()) {
- System.out.println("Interrupt flag for "+ type + " transaction source set. Terminating.");
- return totals;
- }
- }
- return totals;
- }
- private TransactionType type;
- private int maxTrans;
- private Vector<Account> accounts;
- private Vector<Clerk> clerks;
- private int[] totals;
- }
- import java.util.Vector;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Future;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.TimeUnit;
- public class UsingExecutors {
- 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 of credits
- int clerkCount = 2;
- // Create the account, the bank, and the clerks...
- Bank theBank = new Bank(); // Create a bank
- Vector<Clerk> clerks = new Vector<Clerk>(); // Stores the clerk
- Vector<Account> accounts = new Vector<Account>(); // Stores the accounts
- for(int i = 0 ; i < clerkCount ; ++i) {
- clerks.add(new Clerk(i+1, theBank)); // Create the clerks
- }
- for(int i = 0 ; i < initialBalance.length; ++i) {
- accounts.add(new Account(i+1, initialBalance[i])); // Create accounts
- totalCredits[i] = totalDebits[i] = 0;
- }
- ExecutorService threadPool = Executors.newCachedThreadPool();
- // Create and start the transaction source threads
- Future<int[]> credits = threadPool.submit(new TransactionSource(TransactionType.CREDIT, transactionCount, accounts, clerks));
- Future<int[]> debits = threadPool.submit(new TransactionSource(TransactionType.DEBIT, transactionCount, accounts, clerks));
- // Create and start the clerk threads
- for(Clerk clerk : clerks) {
- threadPool.submit(clerk);
- }
- try {
- totalCredits = credits.get();
- totalDebits = debits.get();
- } catch(ExecutionException e) {
- System.out.println(e.getCause());
- } catch(InterruptedException e) {
- System.out.println(e);
- }
- // Orderly shutdown when all threads have ended
- threadPool.shutdown();
- try {
- threadPool.awaitTermination(10L, TimeUnit.SECONDS);
- } catch(InterruptedException e) {
- System.out.println(e);
- }
- if(threadPool.isTerminated()) {
- System.out.println("\nAll clerks have completed their tasks.\n");
- } else {
- System.out.println("\nClerks still running - shutting down anyway.\n");
- threadPool.shutdownNow();
- }
- // Now output the results
- for(int i = 0 ; i < accounts.size() ; ++i) {
- System.out.println("Account Number:"+accounts.get(i).getAccountNumber()+"\n"+
- "Original balance : $" + initialBalance[i] + "\n" +
- "Total credits : $" + totalCredits[i] + "\n" +
- "Total debits : $" + totalDebits[i] + "\n" +
- "Final balance : $" + accounts.get(i).getBalance() + "\n" +
- "Should be : $" + (initialBalance[i]
- + totalCredits[i]
- - totalDebits[i]) + "\n");
- }
- }
- }
Java基础之线程——使用执行器(UsingExecutors)的更多相关文章
- Java基础-多线程-③线程同步之synchronized
使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...
- 【Java基础】线程和并发机制
前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...
- Java基础篇——线程、并发编程知识点全面介绍(面试、学习的必备索引)
原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10739579.html,希望大家多多支持!!! 一.线程基础 1.线程与进程 线程是指进程 ...
- Java基础_线程的使用及创建线程的三种方法
线程:线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 进程:进 ...
- Java基础之线程——管理线程同步方法(BankOperation2)
控制台程序. 当两个或多个线程共享同一资源时,例如文件或内存块,就需要采取措施,确保其中的一个线程不会修改另一个线程正在使用的资源.当其中的一个线程更新文件中的某个记录,同时另一个线程正在检索这个记录 ...
- Java基础之线程——使用Runnable接口(JumbleNames)
控制台程序. 除了定义Thread新的子类外,还可以在类中实现Runnable接口.您会发现这比从Thread类派生子类更方便,因为在实现Runnable接口时可以从不是Thread的类派生子类,并且 ...
- Java基础之线程——派生自Thread类的子类(TryThread)
控制台程序. 程序总是至少有一个线程,程序开始执行时就会创建这个线程.在普通的Java应用程序中,这个线程从mian()方法的开头启动. 要开始执行线程,可以调用Thread对象的start()方法. ...
- Java基础8-多线程;同步代码块
作业解析 利用白富美接口案例,土豪征婚使用匿名内部类对象实现. interface White{ public void white(); } interface Rich{ public void ...
- Java基础-多线程-①线程的创建和启动
简单阐释进程和线程 对于进程最直观的感受应该就是“windows任务管理器”中的进程管理: (计算机原理课上的记忆已经快要模糊了,简单理解一下):一个进程就是一个“执行中的程序”,是程序在计算机上的一 ...
随机推荐
- coursera-miniproject stopwatch任务总结
---恢复内容开始--- 首先是miniproject的说明: combin text drawing in canvas with time to build digital stopwatch. ...
- mysql中文字段转拼音首字母,以及中文拼音模糊查询
创建存储过程,将中文字段转拼音首字母 CREATE DEFINER=`root`@`%` FUNCTION `fristPinyin`(P_NAME VARCHAR(255)) RETURNS var ...
- 区分总结innerHeight与clientHeight、innerWidth与clientWidth、scrollLeft与pageXOffset等属性
window对象: (1)innerHeight属性:窗口中文档显示区域的高度,不包括菜单栏.工具栏等部分.该属性可读可写. IE不支持该属性,IE中body元素的clientHeight属性与该属性 ...
- os相关方法总结
__file__表示当前文件 os.path.dirname表示当前文件所在路径的父路径 os.pardir表示当前文件名 os.path.join表示合并 os.path.abspath表示绝对路径
- Hbase中rowkey设计原则
1.热点问题 在某一时间段,有大量的数据同时对一个region进行操作 2.原因 对rowkey的设计不合理 对rowkey的划分不合理 3.解决方式 rowkey是hbase的读写唯一标识 最大长度 ...
- 修改delphi xe6 FMX Label字体颜色
delphi fmx的字体等设置默认与皮肤有关,用代码直接修改字体颜色等是无效的,如何才能用代码修改呢?请按以下方法就可以: 1.在Object inspector中取消StlyedSettings中 ...
- gradlew常用命令
./gradlew -v 查看版本 ./gradlew clean 清理.下载依赖 ./gradlew build 构建 libgdx项目中的gradlew run: ./gradlew deskt ...
- LINQ之select方法选择多个字段
单个字段: var list1 = list.Select(field1 => field1.CouponID).ToList(); 多个字段: var list1 = list.Select( ...
- 在zendstudio中添加注释
/** * * * @access public * @param string $cat_id 分类查询字符串 * @return string */ 然后在function之前的一行打上/**然后 ...
- imx6 uboot lcd
本文记录imx6 uboot中关于lcd初始化的过程. uboot中相关的文件: cpu/arm_cortexa8/start.S lib_arm/board.c board/freescale/mx ...