java 并发synchronized使用
从版本1.0开始,java中每个对象都有一个内部锁,如果一个方法用synchronized修饰,那么对象的锁将保护整个方法,也就是说要调用该方法,线程必须获得内部的对象锁
换句话说
public synchronized void method(){ method body }
等价于
public void method(){ this.lock(); try{ method body; } finally{this.unlock} }
内部对象只有一个相关条件,wait方法添加一个线程到等待集中,notifyAll方法解除等待线程的阻塞状态
package reentrant_lock; /** * Created by luozhitao on 2017/8/23. */ public class bank_syn { private double [] accounts; public bank_syn(int n,double bance){ accounts=new double[n]; for(int i=0;i<n;i++){ accounts[i]=bance; } } // public synchronized void tansfer(int from,int to,double transf_num) throws InterruptedException{ while (accounts[from]<transf_num) wait(); accounts[from]-=transf_num; System.out.printf("转出账户转出%f 剩余 %10.2f",transf_num,accounts[from]); accounts[to]+=transf_num; System.out.printf("转入账户目前余额为 %10.2f",accounts[to]); notifyAll(); System.out.printf(" 目前所有账户总额为 %10.2f",get_total()); } public synchronized double get_total(){ double sum=0; for (double d:accounts){ sum+=d; } return sum; } // 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 bank_syn bank; private int fromAccount; private double maxAccount; private int DELAY=10; int flag=0; public transferRunnable(bank_syn 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/23. */ public class bank_testsyn { private static int accoun_num=100; private static double init_num=1000; public static void main(String [] args){ bank_syn syn=new bank_syn(accoun_num,init_num); for(int i=0;i<accoun_num;i++){ transferRunnable transferrun = new transferRunnable(syn,i,init_num); Thread t=new Thread(transferrun); t.start(); } } }