package thread.synchronization;
import java.util.Arrays;
public class Bank {
private final double[] accounts;
public Bank(int n,double initialBalance){
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
}
public void transfer(int from ,int to , double amount){
if (accounts[from]<amount) {
return;
}
System.out.println(Thread.currentThread());
accounts[from] -= amount;
System.out.printf("%10.2f from %d to %d",amount,from,to);
accounts[to] += amount;
System.out.printf("Toal Balance:%10.2f%n",getToalBalance());
}
public double getToalBalance(){
double sum=0;
for(double a: accounts){
sum += a;
}
return sum;
}
public int size(){
return accounts.length;
}
}
package thread.synchronization;
public class TestFour {
/**
*
* 同步
*
* 两个线程访问同一共享数据的存取。
*
*
* 竞争条件详解:
* account[to] += amount;
*
* 指令不是原子操作
*
* 将 account[to] 加载到寄存器上
* 增加amount
* 结果写会account[to]
*
* 假设第一个线程执行1,2后,剥夺运行权,执行线程2被唤醒,并修改了accounts数组中的同一项,然后第一个线程被唤醒并完成第三项。 此时值就不对了。
*/
public static final int NACCOUTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final double MAX_AMOUNT = 1000;
public static final int DELAY = 10;
public static void main(String[] args) {
Bank bank = new Bank(NACCOUTS, INITIAL_BALANCE);
for (int i = 0; i < NACCOUTS; i++) {
int fromAccount = i;
Runnable r = () -> {
try {
while(true){
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int) (DELAY*Math.random()));
}
} catch (Exception e) {
e.printStackTrace();
}
};
Thread t = new Thread(r);
t.start();
}
}
}