并发实际场景(保持余额操作的正确)
场景:
一个人在一家银行办了一个账户,银行给了 一张卡(存取款)、一本存折(存取款)、一个网银(查询余额)
卡和存储不断存款和取款,网银不断查询余额。如何保持余额的正确。
例子(线程不安全):
控制器代码:
@Controller
public class TestController {// 开个银行帐号Acount3 account = new Acount3();@RequestMapping(value="/cardAddAcount")@ResponseBodypublic TaotaoResult<Integer> cardAddAcount(){TaotaoResult<Integer> result = new TaotaoResult<Integer>();result.setData("+100, 余额: " + account.addAcount("card", 100));return result;}@RequestMapping(value="/passbookAddAcount")@ResponseBodypublic TaotaoResult<Integer> passbookAddAcount(){TaotaoResult<Integer> result = new TaotaoResult<Integer>();result.setData("+100, 余额: " + account.addAcount("存折", 100));return result;}@RequestMapping(value="/cardSubAcount")@ResponseBodypublic TaotaoResult<Integer> cardSubAcount(){TaotaoResult<Integer> result = new TaotaoResult<Integer>();result.setData("-150, 余额: " + account.subAcount("card", 150));return result;}@RequestMapping(value="/passbookSubAcount")@ResponseBodypublic TaotaoResult<Integer> passbookSubAcount(){TaotaoResult<Integer> result = new TaotaoResult<Integer>();result.setData("-200, 余额: " + account.subAcount("存折", 200));return result;}@RequestMapping(value="/selectAcount")@ResponseBodypublic TaotaoResult<Integer> selectAcount(){TaotaoResult<Integer> result = new TaotaoResult<Integer>();result.setData(account.selectAcount(""));return result;}
}
账户3(线程不安全):
/*** 银行账户:无任何并发处理** @author Administrator*/
public class Acount3 {private int count = 0;/*** 存钱** @param money*/public int addAcount(String name, int money) {// 存钱count += money;System.out.println(name + "...存入:" + money + "..." + Thread.currentThread().getName());return selectAcount(name);}/*** 取钱** @param money*/public int subAcount(String name, int money) {// 先判断账户现在的余额是否够取钱金额if (count - money < 0) {System.out.println("账户余额不足!余额=" + count);return money;}// 取钱count -= money;System.out.println(name + "...取出:" + money + "..." + Thread.currentThread().getName());return selectAcount(name);}/*** 查询余额*/public int selectAcount(String name) {System.out.println(name + "...余额:" + count);return count;}
}
账户3(线程不安全)执行的结果:
例子2:
账户2(线程安全):给每个方法加上synchronized 实现
/*** 银行账户:线程安全** @author Administrator*/
public class Acount2 {private int count = 0;/*** 存钱** @param money*/public synchronized int addAcount(String name, int money) {// 存钱count += money;System.out.println(name + "...存入:" + money + "..." + Thread.currentThread().getName());return selectAcount(name);}/*** 取钱** @param money*/public synchronized int subAcount(String name, int money) {// 先判断账户现在的余额是否够取钱金额if (count - money < 0) {System.out.println("账户余额不足!余额=" + count);return money;}// 取钱count -= money;System.out.println(name + "...取出:" + money + "..." + Thread.currentThread().getName());return selectAcount(name);}/*** 查询余额*/public synchronized int selectAcount(String name) {System.out.println(name + "...余额:" + count);return count;}
}
例子1:
账户1(线程安全):通过lock来实现
import java.util.concurrent.locks.ReentrantLock;/*** 银行账户:线程安全** @author Administrator*/
public class Acount {private int count = 0;private ReentrantLock lock = new ReentrantLock();/*** 存钱** @param money*/public int addAcount(String name, int money) {lock.lock();try {// 存钱count += money;System.out.println(name + "...存入:" + money + "..." + Thread.currentThread().getName());} finally {lock.unlock();}return selectAcount(name);}/*** 取钱** @param money*/public int subAcount(String name, int money) {lock.lock();try {// 先判断账户现在的余额是否够取钱金额if (count - money < 0) {System.out.println("账户余额不足!余额=" + count);return money;}// 取钱count -= money;System.out.println(name + "...取出:" + money + "..." + Thread.currentThread().getName());} finally {lock.unlock();}return selectAcount(name);}/*** 查询余额*/public int selectAcount(String name) {lock.lock();try {System.out.println(name + "...余额:" + count);} finally {lock.unlock();}return count;}
}
代码demo:
链接:https://pan.baidu.com/s/1i_uzZKd-GC-8NPa1hFdw8w 密码:rht7
测试用例:
链接:https://pan.baidu.com/s/1Ri54rR1k7JETO6i5pDyVlw 密码:u96e
并发实际场景(保持余额操作的正确)相关推荐
- 高并发支付场景分析及设计
一.专题分享-高并发支付场景分析及设计1.1 背景 大家好,我是20XX年加入永乐票务,之前一直负责公司票务系统的整体规划.实现.优化及改造.目前主要负责公司的基础平台.支付平台.消息平台.云平台.运 ...
- cache数据库和mysql_并发环境下,先操作数据库还是先操作缓存?
原标题:并发环境下,先操作数据库还是先操作缓存? 来源:捡田螺的小男孩 前言 在分布式系统中,缓存和数据库同时存在时,如果有写操作,先操作数据库还是先操作缓存呢?本文将分5种方案 展开阐述对比,谢谢阅 ...
- SAP 标准带料委外加工 投A产B业务场景及功能操作演示(1)
因为目前在一个模具产业的公司项目上,他们公司业务其实比较具有典型性.当中会涉及到带料委外的业务和工序外协的业务.这几天我把这两个部分业务的场景和系统操作做个记录,然后再结合这个企业的实际业务情况,简化 ...
- 实战分布式之电商高并发秒杀场景总览
前言 本文是新系列"实战高并发"的开篇作.这个系列作为"我说分布式"的子系列,将着重挑选若干典型的分布式实战场景,尽量对当下高并发领域较为热门的架构及业务场景做 ...
- 深入浅出!阿里运维专家三种方法教你如何应对高并发“海啸”场景
作者:田杰,阿里云数据库高级运维专家 在数据库的日常使用中,来自应用的高并发场景并不罕见,其标志性的表现为 高新连接创建速率(CPS,比如 PHP 短连接).发送大量请求到 DB 数据库层. 如同 海 ...
- 在使用win 7 无线承载网络时,启动该服务时,有时会提示:组或资源的状态不是执行请求操作的正确状态。 网上有文章指出,解决这个问题的方法是在设备管理器中启动“Microsoft托管网络虚拟适配
在使用win 7 无线承载网络时,启动该服务时,有时会提示:组或资源的状态不是执行请求操作的正确状态. 网上有文章指出,解决这个问题的方法是在设备管理器中启动"Microsoft托管网络虚拟 ...
- 引领高并发直播场景进入毫秒时代,阿里云发布超低延时直播服务
近日,阿里云上线超低延时直播服务RTS(Real-time Streaming),该服务在视频直播产品的基础上,进行全链路延时监控.传输协议改造等底层技术优化,支持千万级并发场景下的毫秒级延迟直播能力 ...
- 高并发读场景下的利器:本地缓存+分布式缓存
本地缓存和分布式缓存并不是二者取其一甚至对立的关系,而是要结合使用:常见的电商高并发读场景下下,本地缓存存放热点数据,分布式缓存存放全量数据:当然这里有一个很重要的点,即要结合业务,本地缓存中的数据一 ...
- WIN7无法启动承载网络,组或资源的状态不是执行请求操作的正确状态
1.问题 WIN7无法启动承载网络,组或资源的状态不是执行请求操作的正确状态,以及无限网络共享客户端连接不上 2.解决 重启以下Windows服务试试: Wired AutoConfig WLAN A ...
最新文章
- android intent-fliter用法
- CSS3盒模型display:box详解
- Xcode9新特性介绍-中文篇
- PDF转Word技巧,看这篇足够
- php读取数组修改内容,php 数组如何修改值
- T5 PEGASUS:开源一个中文生成式预训练模型
- 请用JavaScript实现一个函数,接受一-个IP白名单列表whitelist以及列表ipList
- 用Android UEventObserver监听内核event
- 面试数据分析岗,怎么提升一倍成功率?让过来人给你支支招
- 苹果mac屏幕录像软件:ScreenFlow
- 【转】SourceInsight4.0的使用--一遍很详细介绍source insight4使用的文章
- linux互信文件,linux SSH互信
- 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图
- math.floor java_Java Math floor、ceil、rint 及 round 用法
- [2019.7.31~2019.8.15]纪中集训游记
- 选择面向 USB4 数据线的 ESD 保护
- MySQL的数值类型
- [置顶] CVT广州视源笔试面试经历(2013实习生招聘)
- 数据分析师兼职副业平台大量招聘
- android 3d魔方 代码,3D--魔方(示例代码)