同步 2

package thread.syn;

import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;

public class Bank {

    private final double[] accounts;
    
    private ReentrantLock bankLock = new ReentrantLock();
    
    public Bank(int n,double initialBalance){
        accounts = new double[n];
        Arrays.fill(accounts, initialBalance); 
    }
    
    
    public void transfer(int from ,int to , double  amount){
        
        bankLock.lock();
        try {
            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()); 
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            bankLock.unlock();
        }
    }
    
    
    public double getToalBalance(){
        double sum=0;
        for(double a: accounts){
            sum += a;
        }
        return sum;
    }
    
    public int size(){
        return accounts.length;
    }
    

}
package thread.syn;

public class TestFour {

    /**
     * 
     * 
     * 
     *
     *14.5.3锁对象 有两种方法阻止受并发访问的干扰
     *1.关键字 synchronized
     *
     *2.java5引入 ReentrantLock
     *
     *每个Bank对象都有自己的ReentrantLock对象,如果两个线程访问同一个Bank对象,将以串行方式访问。
     * 
     * 锁是可以重入的,线程可以重复获取已经持有的锁
     * 
     * lock() 获取这个锁,如果这个锁被其他的线程持有,将会被阻塞
     * 
     * 持有计数:线程有一个持有计数来跟踪对lock方法的嵌套调用,每个lock对应一个unlock,当持有计数为0时,该锁被释放。
     * 
     *  lock()
     *  unlock()
     *  ReentrantLock( ) 
     */
    
    
    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();
        }
    }

}
原文地址:https://www.cnblogs.com/lxh520/p/8467197.html