线程同步的案例

Java当中,对于同步,一般而言,在程序中需完成两个操作:

  1. 把竞争访问的资源标示为private;
  2. 同步那些访问资源的代码,使用synchronize关键字来修饰方法或者代码块,当synchronize方法执行完成或发生异常的时候,会自动的释放锁
    下面用这个例子来讲解:

某银行账号上有500元的现金,一个人拿着正卡去柜台取钱,而另一个人则拿着副卡器ATM机上去取钱,各自取400元钱。
要求:不能出现资源竞争,如同时取出400元,或者取的钱大于500元等;

package hellojava;

/**
 * 某账号上有500块钱,一个人拿着存折去柜台取,另一个人拿着银行卡去ATM机上取
 * 各自想取400块钱
 */
public class BankDemo {
    public static void main(String[] args) {
        Bank b = new Bank();
        BankThread bt1= new BankThread(b);
        bt1.start();
        BankThread bt2 = new BankThread(b);
        bt2.start();
    }

}
class BankThread extends Thread{
    //这样就实现了封装,不用到处new
    private Bank bank=null;
    public BankThread(Bank bank) {
        this.bank=bank;
    }
    @Override
    public void run() {
        System.out.println("取钱:"+bank.getMoney(400));
    }
}
/**
 * 这种情况是不安全的,两个线程同时会去访问,
 * 造成的后果就是各自为营,互不干涉,这不是我们想要的结果
 * Bank才是正确的
 *
 */
class Bank1{
    private int money = 500;
    //取钱的方法,返回取钱的数目
    public int getMoney(int number){
        if(number <0){
            return -1;
        }else if (money<0) {
            return -2;
        }else if (number-money>0) {
            return -3;
        }else {
            //隔了这么久之后,成功的拿到钱
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            money-=number;
            System.out.println("卡上余额:"+money);
        }

        return number;
    }

}
/**
 * 当一个线程去调用一个同步方法的时候,这个线程就获得当前对象的锁
 * 而其他线程去调用这个同步方法的时候,就只能去等待,因为无法获得这个对象的锁
 * 只有等第一个线程释放了对象的锁,才可以去访问,加上synchronized
 * 
 * 或者是在方法体内加上synchronized(){}代码块,括号当中是要锁的对象,比如this,就代表当前对象
 *
 */
class Bank{
    private int money = 500;
    //取钱的方法,返回取钱的数目
    public synchronized int getMoney(int number){
        if(number <0){
            return -1;
        }else if (money<0) {
            return -2;
        }else if (number-money>0) {
            return -3;
        }else {
            //隔了这么久之后,成功的拿到钱
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            money-=number;
            System.out.println("卡上余额:"+money);
        }

        return number;
    }

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值