【发布时间】:2017-07-08 11:34:52
【问题描述】:
注意:线程号 1 = 所有者 1 -> 执行 10 个事务
线程 2 = Owner 2 -> 执行 10 个事务
问题:在输出中:
Owner: 1 transaction: 2
Owner: 1 transaction: 1
credit: $46 credit: $30 balance: $146
balance: $130
交易 2 后余额应为 176 美元。线程池肯定有问题。我尝试了很多,但无法达到所需的解决方案。任何帮助都是不言而喻的。
输出
跑步: 初始余额:100 美元 所有者:1 笔交易:1 所有者:1 交易:2 贷方:46 美元贷方:30 美元余额:146 美元 余额:$130 所有者:2 交易:1 所有者:2 交易:2 借方:46 美元借方:30 美元借方完成借方完成余额:100 美元余额:100 美元 所有者:1 笔交易:3 信用:75 美元所有者:1 次交易:4 余额:175美元 信用:47 美元所有者:2 次交易:3 余额:147美元 所有者:2 交易:4 借方:47 美元借方:75 美元借方完成借方完成余额:100 美元余额:100 美元 所有者:1 笔交易:5 信用:57 美元所有者:1 次交易:6 余额:157美元 信用:13 美元所有者:2 次交易:5 余额:$113 借记:57 美元 借记完成 所有者:2 次交易:6 余额:100 美元借记:13 美元借记完成余额:100 美元所有者:1 笔交易:7 信用:84 美元所有者:1 笔交易:8 余额:184 美元 信用:95 美元所有者:2 次交易:7 余额:195美元 所有者:2 交易:8 借方:84 美元借方完成借方:95 美元借方完成余额:100 美元余额:100 美元 所有者:1 笔交易:10 笔信用:96 美元余额:196 美元 所有者:1 笔交易:9 所有者:2 交易:10 贷方:20 美元借方:96 美元借方完成余额:120 美元 余额:100 美元 所有者:2 交易:9 借记:$20 借记完成余额:$100B银行
public class Bank{
private BankAccount bankAccount = new BankAccount(100);
public void displayInitialBalance(){
System.out.println("Initial Balance:"+getBankAccount());
}
/**
* @return the bankAccount
*/
public BankAccount getBankAccount() {
return bankAccount;
}
/**
* @param bankAccount the bankAccount to set
*/
public void setBankAccount(BankAccount bankAccount) {
this.bankAccount = bankAccount;
}
public static void main(String[] args){
BankAccount bankAccount = new BankAccount(100);
System.out.println("Initial Balance: $"+bankAccount.getCurrentBalance());
ExecutorService executorService = Executors.newFixedThreadPool(2);
for(int count = 1; count<=10; count++){
Runnable runnable = new Owner(count);
executorService.execute(runnable);
}
executorService.shutdown();
while(!executorService.isTerminated()){
}
System.out.println("All Transactions Done");
}
}
银行账户
public class BankAccount {
private int currentBalance;
public BankAccount(int initialBalance){
this.currentBalance = initialBalance;
}
synchronized public void credit(int amount){
setCurrentBalance(currentBalance + amount);
System.out.print("credit: $"+amount+"\t");
System.out.println(" balance: $"+getCurrentBalance());
}
synchronized public void debit(int amount){
if(getCurrentBalance() >= amount){
setCurrentBalance(currentBalance - amount);
System.out.print(" debit: $"+amount);
System.out.print(" Debit Done" +"\t");
System.out.print(" Balance: $"+getCurrentBalance());
}
else{
System.out.print("Insufficient Balance"+"\t");
System.out.println("Balance: $"+getCurrentBalance());
}
}
/**
* @return the currentBalance
*/
public int getCurrentBalance() {
return currentBalance;
}
/**
* @param currentBalance the currentBalance to set
*/
public void setCurrentBalance(int currentBalance) {
this.currentBalance = currentBalance;
}
}
所有者
public class Owner implements Runnable{
public int transactionCount = 0;
public int amount = 0;
private BankAccount bankAccount = new BankAccount(100);
public Owner(int transactionCycle){
this.transactionCount = transactionCycle;
}
public Owner(int transactionId, BankAccount bankAccount){
this.bankAccount = bankAccount;
this.transactionCount = transactionId;
}
@Override
public void run() {
try{
amount = (int)(Math.random() * 100 + 10);
Thread call = new Thread();
call.start();
Thread.currentThread().setName("Owner: 1 "+" transaction: "+transactionCount);
(transactionCount)++;
System.out.println(Thread.currentThread().getName());
getBankAccount().credit(amount);
Thread.currentThread().setName("Owner: 2 "+" transaction: "+ --(transactionCount));
(transactionCount)++;
System.out.println(Thread.currentThread().getName());
getBankAccount().debit(amount);
}catch(UnsupportedOperationException e){
e.printStackTrace();
}
}
/**
* @return the bankAccount
*/
public BankAccount getBankAccount() {
return bankAccount;
}
/**
* @param bankAccount the bankAccount to set
*/
public void setBankAccount(BankAccount bankAccount) {
this.bankAccount = bankAccount;
}
}
【问题讨论】:
-
你有一个你从不实例化的类
Bank,不可编译的代码,一个什么都不做的Thread call,即使你在不同的线程中运行该代码,同步也不充分。BankAccount实例永远不会从多个线程直接访问,但它是部分(!)同步的,Owner实例是从多个线程访问的(或将是),但它没有同步方法。除其他事项外(如修复编译器错误),我建议制作Owner#bankAccountfinal并开始构建。不是现在的两倍。 -
您对 Thread 调用是正确的,我已将其删除。但我不明白的是,我将
BankAccount instance更改为final 并从Constructor调用它一次,但同步仍然出错private final BankAccount bankAccount; public Bank(){ bankAccount = new BankAccount(100); } -
现在所有代码都工作正常,执行正确的计算只有一个问题出现在
output formatOwner: 1 transaction: 1 credit: $10 Balance: $110 Owner: 2 transaction: 1 debit: $48 Debit Done??Owner: 1 transaction: 2 Balance: $62 credit: $88 Balance: $150 Owner: 2 transaction: 2 debit: $85 Debit Done Balance: $65我把**放在哪里??Balance $62必须在那里打印 -
“线程池中一定有问题” -- 极不可能,问题很可能出在您的代码中。请访问help center,阅读How to Ask,也阅读Why is “Can someone help me?” not an actual question?
-
我也在努力寻找解决方案。
标签: java multithreading threadpool