14 同步 1

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

}

 

posted @ 2018-02-13 10:55  aLa神灯  阅读(129)  评论(0编辑  收藏  举报