-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMultiUserBalanceTransfer.java
More file actions
122 lines (105 loc) · 4.15 KB
/
Copy pathMultiUserBalanceTransfer.java
File metadata and controls
122 lines (105 loc) · 4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package exp3;
public class MultiUserBalanceTransfer {
public static void main(String[] args) {
BankAccount bank = null;
try {
bank = new BankAccount(0);
} catch (InvalidAmountException e) {
System.err.println("[-] Failed to create bank account: " + e.getMessage());
System.exit(1);
}
Customer customer1 = new Customer(
bank,
new double[]{100, 200, 300, 400, 500},
new long[]{
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000)
100, 100, 100, 100, 100
});
Customer customer2 = new Customer(
bank,
new double[]{500, 400, 300, 200, 100},
new long[] {
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000),
// RandomDelayGenerator.generate(100, 1000)
100, 100, 100, 100, 100
});
Thread thread1 = new Thread(customer1, "Customer-1");
Thread thread2 = new Thread(customer2, "Customer-2");
thread1.start();
thread2.start();
}
}
class WalletException extends Exception {
public WalletException(String message) {
super(message);
}
}
class InvalidAmountException extends WalletException {
public InvalidAmountException(String message) {
super(message);
}
}
class RandomDelayGenerator {
public static long generate(long minDelay, long maxDelay) {
return minDelay + (long) (Math.random() * (maxDelay - minDelay));
}
}
class Customer implements Runnable {
private BankAccount target;
private double[] amounts; // 多次汇款的每次汇款金额
private long[] delays; // 每次汇款的延迟时间
public Customer(BankAccount target, double[] amounts, long[] delays) {
this.target = target;
this.amounts = amounts;
this.delays = delays;
System.out.println("[*] Customer " + Thread.currentThread().getName() + " is created with amounts: " + java.util.Arrays.toString(amounts) + " and delays: " + java.util.Arrays.toString(delays));
}
@Override
public void run() {
for (int idx = 0; idx < amounts.length; idx++) {
double amount = amounts[idx];
long delay = delays[idx];
System.out.println("[*] Customer " + Thread.currentThread().getName() + " is transferring: " + amount);
try {
double newBalance = target.deposit(amount);
System.out.println("[+] Customer " + Thread.currentThread().getName() + " transferred " + amount + ". New balance: " + newBalance);
} catch (InvalidAmountException e) {
System.err.println("[-] Failed to transfer amount " + amount + " with error: " + e.getMessage());
}
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("[!] Thread interrupted while sleeping.");
}
}
}
}
class BankAccount {
private double balance;
BankAccount(double balance) throws InvalidAmountException {
if (balance < 0) {
throw new InvalidAmountException("[!] Invalid account balance. Balance cannot be negative.");
}
this.balance = balance;
}
public double getBalance() {
return balance;
}
public double deposit(double amount) throws InvalidAmountException {
if (amount < 0) {
throw new InvalidAmountException("[!] Invalid deposit amount. Amount cannot be negative.");
}
synchronized (this) {
this.balance += amount;
}
return this.balance;
}
}