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(); } } }