java中多线程知识点 ---- 线程同步问题

前面几篇简单介绍完线程概念、创建与启动以及线程的状态,现在来把线程同步问题梳理一下,看看为什么要考虑线程同步的问题

最平常的例子,银行ATM机取钱问题,一提到钱小白就激动…

模拟一下同一个账户不同用户进行取钱操作,纯粹只是为了模拟

import java.util.*

//封装银行账号以及密码的相关类
public class Account {

    //账号
    private String accountName;

    //余额
    private double balance;

    public Account(String accountName, double balance) {
        this.accountName = accountName;
        this.balance = balance;
    }

    public Account() {
    }

    public String getAccountName() {
        return accountName;
    }

    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }

    public double getBalance() {
        return balance;
    }

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

package com.MrLiu.group.account;

public class AccountThread  extends  Thread{

    private Account account;
    private double drowMoney;
    //取钱账号
    public AccountThread(String name,Account account,double drowMoney){
        super(name);
        this.account = account;
        this.drowMoney = drowMoney;
    }

    @Override
    public void run() {
        try {
            if (account.getBalance() >= drowMoney){
                System.out.println(getName()+"取钱成功,金额为"+  drowMoney);
                //更新账户余额
                account.setBalance(account.getBalance() - drowMoney);
                System.out.println("当前账户余额为" + account.getBalance());
            }else{
                System.out.println(getName()+"取钱失败");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

//用户开始取钱
class DrowClazz{

       public static void main(String[] args) {

           //新建账户  账号888888   余额10000
           Account account =  new Account("888888",10000);
           //用户1 开始取钱
           new AccountThread("用户一",account,10000).start();
           //用户2 开始取钱
           new AccountThread("用户二",account,10000).start();
     }
}

在这里插入图片描述
只要10K的账户取出了20K的钱,多么希望这是真的…不过别做白日梦了,这在现实中是绝对不允许的.之所以会出现这种现象,是因为run()方法不具有同步安全性,两个线程同时对同一个Account对象进行修改操作,造成数据的紊乱.

为了不使多个线程对同一个资源做出不同操作而造成的数据错误问题,java引进了一个同步监视器解决对同一个资源的合理操作.
关键字为 synchronized
语法 synchronized (object){ }
语法中的 object 通常是被并发访问的共享资源
所以,上面的线程执行体可以变成

			 //银行账户作为共享资源
            //完成  对该资源加锁  修改  解锁  整个过程
            //资源被一个线程加锁后,其他线程无法进行访问,必须等到拥有锁的线程释放之后才能获取
            synchronized (account){
                if (account.getBalance() >= drowMoney){
                    System.out.println(getName()+"取钱成功,金额为"+  drowMoney);
                    //更新账户余额
                    account.setBalance(account.getBalance() - drowMoney);
                    System.out.println("当前账户余额为" + account.getBalance());
                }else{
                    System.out.println(getName()+"取钱失败");
                }
            }

加锁之后运行代码会发现,无论运行几次都是出现 相同的结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值