概述
前面几篇简单介绍完线程概念、创建与启动以及线程的状态,现在来把线程同步问题梳理一下,看看为什么要考虑线程同步的问题
最平常的例子,银行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()+"取钱失败");
}
}
加锁之后运行代码会发现,无论运行几次都是出现 相同的结果
最后
以上就是柔弱大雁为你收集整理的java中多线程知识点 ---- 线程同步问题的全部内容,希望文章能够帮你解决java中多线程知识点 ---- 线程同步问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复