博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程同步&案例详解
阅读量:1812 次
发布时间:2019-04-25

本文共 2439 字,大约阅读时间需要 8 分钟。

【1】对于同步需要完成的两个操作

    >吧竞争访问资源标识为private

    >同步那些访问资源的代码,使用synchronized关键字来修饰方法或代码块。当synchronized方法执行完或者发生异常自动释放锁

【案例】

    >模拟银行取钱,某银行卡账号上有500,一个人拿着存折去取钱,另外一个人拿着ATM去取钱,各自取钱400,要求取钱过程中不能出现资源竞争

    >没有使用synchronized去模拟取钱的情况

public class BankDem0 {	public static void main(String[] args) {		Bank bank = new Bank();		BankThread b1 = new BankThread(bank);//模拟存折取款		b1.start();		BankThread b2 = new BankThread(bank);//模拟ATM机取款		b2.start();	}}class BankThread extends Thread{	private Bank bank = null;    public BankThread(Bank bank) {		this.bank = bank;	}		@Override	public void run() {		System.out.println("取款"+bank.getMoney(400));//设置取款金额为500	}}class Bank{	private int money = 500;	public int getMoney(int number) {		if(number < 0) {//判断取款金额是否正确			return -1;		}else if(money < 0) {//判断账户里面的余额是否正确			return -2;		}else if(number > money) {//判断取款金额是否超过存折里面的金额			return -3;		}else {			try {				Thread.sleep(1000);//休眠1秒			} catch (InterruptedException e) {				e.printStackTrace();			}					}		money-=number;//取钱之后存款的余额		System.out.println("余额"+money);//输出余额		return number;	}		}

    >输出结果

余额-300    余额100

取款400     取款400
余额-300    余额-300

取款400     取款400    

    >结果分析

(1)   对于出现结果1,我们可以这样理解,当b1执行的时候调用run()方法,然后在调用getMoney()方法,此时符合这里面的前三个判断,则此时需要休眠1秒,而此时b2开始执行了,当b2页执行到这里的时候,b1开始进行money-=number,此时余额为100,而此时b2休眠完了,也执行到这里,故余额为100-400=-300,此时b1和b2共同执行输出语句,就会出现余额为-300

(2)  对于结果2,我们可以在(1)的基础上这样解释,当b2刚休眠的时候b1就将money的余额相减然后直接输出,也就没等到和b2一起输出,所以就会是这样的结果

 >使用synchronized去模拟取钱的情况

public class BankDem0 {	public static void main(String[] args) {		Bank bank = new Bank();		BankThread b1 = new BankThread(bank);//模拟存折取款		b1.start();		BankThread b2 = new BankThread(bank);//模拟ATM机取款		b2.start();	}}class BankThread extends Thread{	private Bank bank = null;    public BankThread(Bank bank) {		this.bank = bank;	}		@Override	public void run() {		System.out.println("取款"+bank.getMoney(400));//设置取款金额为500	}}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) {//判断取款金额是否超过存折里面的金额			return -3;		}else {			try {				Thread.sleep(1000);//休眠1秒			} catch (InterruptedException e) {				e.printStackTrace();			}					}		money-=number;//取钱之后存款的余额		System.out.println("余额"+money);//输出余额		return number;	}		}

    >输出结果

    余额100

    取款-3

    取款400

    >结果分析

    当一个线程去调用同步方法的时候,这个线程就获取了当前对象的锁,而其他线程去调用同步方法的时候只能等待,因为无法获取对象的锁,因此只能等待第一个线程释放对象的锁方可进入。

例如第一次取了400余额剩余100,第二次再去取钱因为number>money 所以返回-3

转载地址:http://gdozf.baihongyu.com/

你可能感兴趣的文章
sql面试题
查看>>
linux基础与调优
查看>>
软件缺陷基础
查看>>
软件测试-面试13问
查看>>
记一次django项目的部署
查看>>
测试项目调研
查看>>
接手软件测试新项目的流程
查看>>
jmeter-性能测试2-脚本录制开发
查看>>
jmeter-性能测试3-参数化
查看>>
期货基础知识
查看>>
期权基础
查看>>
jmeter-性能测试6-性能基础扫盲
查看>>
pytest+allure生成测试报告
查看>>
接口测试用例
查看>>
vnc安装配置
查看>>
Allure 测试报告:allure.title 去掉后方的参数化显示
查看>>
appium起源-环境配置
查看>>
appium初识-firstdemo
查看>>
allure报告的定制化
查看>>
怎样给excel添加一行数据
查看>>