我正在尝试使用多线程模拟单个银行帐户上的两个用户,撤回并存入资金。我希望两个用户对单个共享变量进行操作,当然代表帐户余额。
存款或取款的行为是随机选择的 - 1或2(分别存款和取款)。存款时,我希望存款操作需要1秒钟,撤销操作需要0.5秒。在此时间间隔内,线程必须等待另一个线程完成操作才能撤回/存放自己。
然而,我最大的问题是两个线程如何编辑单个共享数字字段,即余额。我第一次尝试时,每个线程都创建了自己的余额实例,并分别对它们进行了操作。我希望每个线程的操作(撤销/存款)影响全局字段“平衡” - 而不是实例字段。
我到目前为止构建的线程类和Driver类。
线程创建者类:
public class BankAccountSim extends Thread{
public double balance = 1000;
public String threadName;
BankAccountSim(String name){
threadName = name;
}
public void run(){
System.out.println(threadName + "account initiated.");
while(true){
try{
Random rand = new Random();
int num = rand.nextInt(2) + 1;
if(num == 1){
System.out.println(threadName + " is depositing in the bank.");
balance += 1;
System.out.println("The new balance is " + balance + " dollars" );
Thread.sleep(1000);
Thread.yield();
}
else{
System.out.println(threadName + " is withdrawing from the bank.");
balance -= 1;
System.out.println("The new balance is " + balance + " dollars.");
Thread.sleep(500);
Thread.yield();
}
}
catch(InterruptedException e){
System.out.println("Process terminated.");
}
}
}
}
线程驱动程序类:
import java.util.concurrent.ThreadLocalRandom;
import java.util.Random;
public class BankAccountSimDriver {
public static void main(String[] args){
Thread user1 = new BankAccountSim("user1");
Thread user2 = new BankAccountSim("user2");
user1.start();
user2.start();
}
}
答案 0 :(得分:0)
这主要是一个设计问题。您最好创建一个银行帐户并与客户共享,就像在现实世界中一样。
interface BankAccount {
// Query the balance
BigDecimal balance();
// Make a deposit and return the new balance
BigDecimal deposit(BigDecimal amount);
// Make a withdrawal and return the new balance
BigDecimal withdraw(BigDecimal amount);
}
// Implements the Runnable interface for run in another thread.
class BankClient implements Runnable {
private final String clientName;
private final BankAccount bankAccount;
public BankClient(String clientName, BankAccount bankAccount) {
this.clientName = clientName;
this.bankAccount = bankAccount;
}
public void run() {
// while(true) ...
}
}
class SimpleBankAccount implements BankAccount {
private BigDecimal balance = BigDecimal.ZERO;
public SimpleBankAccount(BigDecimal initialBalance) {
this.balance = initialBalance;
}
public synchronized BigDecimal balance () {
return balance;
}
public synchronized BigDecimal deposit(BigDecimal amount) {
return balance = balance.add(amount);
}
public synchronized BigDecimal withdraw(BigDecimal amount) {
if (balance.compareTo(amount) < 0) {
throw new RuntimeException("Not enough balance.");
}
return balance = balance.subtract(amount);
}
}
public class SimDriver {
public static void main(String[] args) throws Exception {
BankAccount account = new SimpleBankAccount(BigDecimal.valueOf(1000));
Thread t1 = new Thread(new BankClient("client-1", account));
thread t2 = new Thread(new BankClient("client-2", account));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
答案 1 :(得分:0)
有趣的是,你想要一个自己的线程,但是,不要认为with open("file.txt") as myFile:
for strLine in myFile:
if "item" not in strLine:
continue
for strLine in myFile: #using same counter as outer loop
processitemdata() # Should you test for ">" first?
if ">" in strLine:
break
是一个线程,Action是一个线程。关于这个设计的一点说明。我个人的经验法则是我只使用BankAccount
作为原始类型。如果您将volatile
更改为balance
或其他对象,请锁定Double
或使用Object
或其他内容。
AtomicReference
答案 2 :(得分:0)
一个简单的解决方案是通过更改:{/ p>来平衡AtomicInteger
public double balance = 1000;
以强>
public AtomicInteger balance = new AtomicInteger(1000);
然而,您需要稍微修改更新余额的方式,例如添加到余额中:
balance.addAndGet(1);