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