java编程多线程并发处理实例解析

所属分类: 软件编程 / java 阅读数: 31
收藏 0 赞 0 分享

本文主要是通过一个银行用户取钱的实例,演示java编程多线程并发处理场景,具体如下。

从一个例子入手:实现一个银行账户取钱场景的实例代码。

第一个类:Account.java

账户类:

package cn.edu.byr.test;
public class Account {
	private String accountNo;
	private double balance;
	public Account(){
	}
	public Account(String accountNo,double balance){
		this.accountNo = accountNo;
		this.balance = balance;
	}
	public int hashcode(){
		return accountNo.hashCode();
	}
	public String getAccountNo(){
		return this.accountNo;
	}
	public double getBalance(){
		return this.balance;
	}
	public void setBalance(double balance){
		this.balance = balance;
	}
	public Boolean equals(Object obj){
		if(this == obj) 
		      return true;
		if(obj != null && obj.getClass() == Account.class){
			Account target = (Account)obj;
			return target.getAccountNo().equals(accountNo);
		}
		return false;
	}
}

第二个类:DrawThread.java

取钱线程类:

package cn.edu.byr.test;
public class DrawThread extends Thread {
	private Account account;
	private double drawAmount;
	public DrawThread(String name,Account account,double drawAmount){
		super(name);
		this.account = account;
		this.drawAmount = drawAmount;
	}
	public void run(){
		//   synchronized (account) { 
		if(account.getBalance() > drawAmount){
			System.out.println(getName() + "取钱成功,吐出钞票:" + drawAmount);
			//       try{ 
			//         Thread.sleep(1); 
			//       } 
			//       catch(InterruptedException e){ 
			//         e.printStackTrace(); 
			//       } 
			account.setBalance(account.getBalance() - drawAmount);
			System.out.println("\t 余额为 : " + account.getBalance());
		} else 
		        System.out.println(getName() + "取钱失败,余额不足!");
		//   }
	}
	public static void main(String[] args){
		Account acct = new Account("123456",1000);
		new DrawThread("A",acct,800).start();
		new DrawThread("B",acct,800).start();
	}
}

上面代码中注释掉的部分:(1)synchronized同步代码块 (2)线程休眠。如果注释掉(1)、(2),则运行结果有多种可能性,可能性之一(概率较小),符合正常逻辑:

B取钱成功,吐出钞票:800.0
余额为 : 200.0
A取钱失败,余额不足!

应该是B先强找到取钱资源,并且正确修改余额后,A才开始判断用户余额;这种概率非常小,多数运行会类似以下情况:

A取钱成功,吐出钞票:800.0
B取钱成功,吐出钞票:800.0
余额为 : -600.0
余额为 : 200.0

这明显是不符合逻辑的,从运行结果可以猜测,A先抢占资源,取出金额,但在修改余额之前,资源被B抢占;由于余额未被修改,则B看到余额仍然是800,B仍然取出金额;A先运行修改余额,但并未打印,B抢夺资源;B修改余额,并打印余额,为-600;A打印余额,为200;

如果加上(2)线程休眠,则一定是错误状况,因为A或B在取出金额后一定会因为sleep释放CPU资源,JVM会调用其他处于准备状态的进程。第二个取钱判断余额一定是错误的。

如果加上(1)synchronized同步代码块,在线程run方法体中对account进行加锁;则每次都会保证执行逻辑正常:

A取钱成功,吐出钞票:800.0
余额为 : 200.0
B取钱失败,余额不足!
可以设想一下执行过程:

A先抢占资源,在run方法体初始对account类进行加锁;然后开始执行同步代码块;如果执行到中间某个环节,CPU资源被B抢占;B开始执行,一开始也会对account类进行加锁。但是加锁时会发现account已经被A占用,则会调整为阻塞状态等待A释放资源;A执行完同步代码块后释放account的锁,B继续执行;B运行时看到的余额保证是A已经修改过的,会按照正确逻辑正常执行。

总结

以上就是本文关于java编程多线程并发处理实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

更多精彩内容其他人还在看

java实现背单词程序

这篇文章主要为大家详细介绍了java实现背单词程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

java实现单词查询小程序

这篇文章主要为大家详细介绍了java实现单词查询小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java程序开发环境配置图文教程

这篇文章主要为大家详细介绍了Java程序开发环境配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解ssh框架原理及流程

在本文中小编给大家整理的是关于ssh框架原理及流程的相关知识点内容,有此需要的朋友们可以学习下。
收藏 0 赞 0 分享

Java实现弹窗效果的基本操作

这篇文章主要为大家详细介绍了Java实现弹窗效果的基本操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解springmvc常用5种注解

在本篇里我们给大家总结了关于springmvc常用5种注解相关知识点以及实例代码,需要的朋友们参考下。
收藏 0 赞 0 分享

Java实现弹窗效果的基本操作(2)

这篇文章主要为大家详细介绍了Java实现弹窗效果的基本操作第二篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Spring Boot假死诊断实战记录

这篇文章主要给大家介绍了关于Spring Boot假死诊断的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Java计时新姿势StopWatch详解

这篇文章主要介绍了Java计时新姿势StopWatch,最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时的新姿势「StopWatch」,需要的朋友可以参考下
收藏 0 赞 0 分享

java实现点击按钮弹出新窗体功能

这篇文章主要为大家详细介绍了java实现点击按钮弹出新窗体功能,旧窗体不进行操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多