同一银行账户使用线程同步机制,解决线程安全问题

package com.javase.threadsafe2;
/**银行账户
* 使用线程同步机制,解决线程安全问题
*/
public class Account {
    //账户
    private String actno;
    //余额
    private double balance;

    //无参构造
    public Account() {
    }

    //有参构造
    public Account(String actno, double balance) {
        this.actno = actno;
        this.balance = balance;
    }

    //set and get 
    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    //取款方法
    public void withdraw(double money){
        //以下这几行代码必须是线程排队的,不能并发,一个线程执行结束之后,另一个线程才能进来
        /*
        线程同步机制的语法是
            synchronized (){
                线程同步代码块
            }
         在java语言中,任何对象都有一把锁,其实这把锁就是一个标记,(只是把它叫做锁)
        */

        //synchronized (),小括号中的内容特别关键,必须是需要进行排队的多个线程共享的数据
        /*
        比如:一共有三个线程t1、t2、和t3,其中t1 t2是操作同一个账户,t3是操作另一个账户,这种情况之下t1与t2两个线程需要排队而
            t3线程不需要排队,为此synchronized ()小括号中应该写的是t1和t2线程共享的对象,并且该共享对象不能是t3线程的共享对象
        */
        synchronized (this){//这里写的不一定是this,也可以是别的共享对象
            double before = this.getBalance();
            //取款后余额
            double after = before - money;
            //这里模拟网络延迟,在没有使用线程同步机制时百分之百出现问题,使用线程同步机制以后就不会出现问题
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //更新余额
            this.setBalance(after);
        }
    }
}
package com.javase.threadsafe2;

public class AccountThread extends Thread{
//    两个线程必须共享同一个账户对象
    private Account act;
//    构造方法
    public AccountThread(Account act) {
        this.act = act;
    }

    @Override
    public void run() {
//        run()方法的执行表示取款。假设取款5000元
        double money = 5000;
        act.withdraw(money);
        System.out.println(Thread.currentThread().getName() + "对" + act.getActno() + "取款" + money +"成功,余额:" + act.getBalance());
    }
}
package com.javase.threadsafe2;

public class Text {
    public static void main(String[] args) {
//        创建账户对象
        Account act = new Account("act-002",10000);
//        创建两个线程
        Thread t1 = new AccountThread(act);
        Thread t2 = new AccountThread(act);
//        设置线程名称
        t1.setName("t1");
        t2.setName("t2");
//        启动线程
        t1.start();
        t2.start();
    }
}

/*

采用线程同步机制以后就不会出现线程安全问题

程序运行结果:

        t1对act-002取款5000.0成功,余额:5000.0
        t2对act-002取款5000.0成功,余额:0.0

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值