同步 3

package thread.syn2;

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 synchronized void transfer(int from ,int to , double  amount){
        
        try {
            if (accounts[from]<amount) {
                wait();
            }
            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()); 
            
            notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
        }
    }
    
    
    public double getToalBalance(){
        double sum=0;
        for(double a: accounts){
            sum += a;
        }
        return sum;
    }
    
    public int size(){
        return accounts.length;
    }
    

}
package thread.syn2;

public class TestSix {

    /**
     * 14.5.5 synchronized 关键字
     * 
     * 所可以执行代码片段,任何时候只有一个线程可以执行被保护的代码片段
     * 锁可以管理试图进入被保护的代码片段的线程
     * 锁可以有一个或多个条件对象
     * 每个条件对象管理那些已经进入被保护的代码片段但是还不能运行的线程
     * 
     * java 1开始每个对象都有一个内部锁
     * 
     * 如果一个方法用synchronized声明,对象的锁将保护整个方法。如果想调用这个方法,必须获得内部的对象锁。
     * 
     * 
     * 用synchronized代替显示的锁
     * 
     * 
     * 
     * wait() 等价于 await()
     * 
     * notifyAll() 等价于 signalAll()
     * 
     * 
     * 
     * 内部锁和条件对象有局限性
     * 不能中断一个视图获取内部锁的线程
     * 试图获取锁时,不能设定超时
     * 每个锁单一条件可能是不够的
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     */
    
    
    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/8467207.html