Java多线程学习——synchronized锁机制

Java在多线程中使用同步锁机制时,一定要注意锁对对象,下面的例子就是没锁对对象

例子:两个人操作同一个银行账户,丈夫在ATM机上操作,妻子在银行柜台操作

账户类:账户里面有100万

public class Acount {
    public int money=100;
}

ATM机类:里面存在一个Acount对象和要取的钱数,在takeMoney方法中加了synchronized 机制

public class ATM implements Runnable{
    private Acount acount;
    private int withdrawMoney;

    public ATM(Acount acount, int withdrawMoney) {
        this.acount = acount;
        this.withdrawMoney = withdrawMoney;
    }

    @Override
    public void run() {
        takeMoney();
    }

    public synchronized void takeMoney(){    //取钱
        if(acount.money<withdrawMoney){
            return;
        }
        try {
            Thread.sleep(200);  //线程1进入后休眠,线程2仍可以进来,这样可能造成赤字
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"取出"+withdrawMoney+"万元");
        acount.money-=withdrawMoney;
        System.out.println("账户余额:"+acount.money);
    }
}

客户类:创建一个唯一账户,两台ATM机(其中一台模拟柜台),分别给两个人使用

public class Customer {
    public static void main(String[] args) {
        Acount acount=new Acount();
        ATM atm1=new ATM(acount,70);    //丈夫在ATM机上操作账户,妻子在柜台操作账户
        ATM atm2=new ATM(acount,80);
        Thread husband=new Thread(atm1,"丈夫");
        Thread wife=new Thread(atm2,"妻子");

        husband.start();
        wife.start();
    }
}

运行结果:

可以看到加了synchronized 后仍然出现线程不安全。

分析:synchronized 机制一般用在被数据操作的对象中,而takeMoney方法是属于ATM机的方法,在此例子中,一共存在一个账户类,两个ATM机类,两个ATM机类去操作账户类,所以应该把账户类锁住。

猜你喜欢

转载自www.cnblogs.com/chiweiming/p/11109078.html