java 并发时使用条件变量--Condition

lock--unlock的方式在实际中使用较少,一般使用synchronized获取对象的内部锁替代,但是lock--unlock对了解synchronized有很大的帮助。

创建一个bank对象用于模拟动作

package reentrant_lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by luozhitao on 2017/8/18.
 */
public class Bank {

    private final double[] accounts;
    private Lock bankLock;
    private Condition newCondition;

    public Bank(int n,double intialBalance){


        accounts=new double[n];

        for(int i =0;i<n;i++){
            accounts[i]=intialBalance;
        }

        bankLock=new ReentrantLock();
        newCondition=bankLock.newCondition();

    }



    //
    public void tansfer(int from,int to,double account_m) throws InterruptedException{

        bankLock.lock();
        int aa=0;

        try{

        while (accounts[from]<account_m) {
            System.out.println(Thread.currentThread()+"被阻塞");
            aa++;
            newCondition.await();
        }

            if(aa>0) {
                System.out.println(Thread.currentThread()+"从阻塞状态被唤醒");
                aa=0;

            }

            accounts[from]-=account_m;

            System.out.printf("%10.2f from %d to %d",account_m,from,to);

            accounts[to]+=account_m;
            System.out.println("-----");
            System.out.printf("the total banlance %10.2f", getTotal());

            System.out.println("释放transfer锁之前");
            //newCondition.notifyAll();
            newCondition.signalAll();
            System.out.println("释放transfer锁之后");





        }

        finally {

            bankLock.unlock();

        }



    }


    //
    public double getTotal(){

        bankLock.lock();
        try{
            double sum=0;
            for(double a:accounts){


                sum+=a;
            }

            return sum;

        }finally {
            bankLock.unlock();

        }

    }

//

    public int size(){

        return accounts.length;
    }
}

创建线程

package reentrant_lock;

/**
 * Created by luozhitao on 2017/8/18.
 */
public class transferRunnable implements Runnable {

    private Bank bank;
    private int fromAccount;
    private double maxAccount;
    private int DELAY=10;
    int flag=0;


    public transferRunnable(Bank b,int from,double max){
        this.bank=b;
        this.fromAccount=from;
        this.maxAccount=max;

    }




    public void run() {


        try{
            while (true){
                int toAccount=(int)((bank.size()-1)*Math.random());

                System.out.println("toAccount ="+toAccount);
                double account_m=maxAccount*Math.random();
                System.out.println("account_m is "+account_m);
                bank.tansfer(fromAccount,toAccount,account_m);

                Thread.sleep((int) (DELAY * Math.random()));
                flag++;


            }
        }catch (InterruptedException e){e.printStackTrace();}

    }
}

main

package reentrant_lock;

/**
 * Created by luozhitao on 2017/8/18.
 */
public class Banktest {


    private static final int Naccount=100;
    private static final double inital_balance=1000;

    public static  void main(String [] args){



        Bank b=new Bank(Naccount,inital_balance);

        for(int i=0;i<100;i++){

            transferRunnable t=new transferRunnable(b,i,inital_balance);

            Thread thread=new Thread(t);
            thread.start();



        }





    }


}
原文地址:https://www.cnblogs.com/luo-mao/p/7405046.html