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

        }



    }

}

 

posted on 2017-08-23 19:08  猫儿爹  阅读(161)  评论(0编辑  收藏  举报

导航