- 1、本文档共11页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
第
java并发无锁多线程单线程示例详解
目录前言场景单线程多线程悲观锁无锁最后
前言
在并发编程中,多线程的共享资源的修改往往会造成严重的线程安全问题,解决这种问题简单暴力的方式就是加锁,加锁的方式使用简单易理解,但常常会因为阻塞导致性能问题
有没有可能做到无锁还保证线程安全呐?这得看具体情况。得益于CAS技术,有很多情况下我们可以做到不使用锁也能保证线程的安全
比如今天我最近遇到的场景如下(由于场景比较复杂,用一个模拟简化一下)
场景
假设有一个商店,背后有一个工厂可以生产商品,商店也可以有用户来购买商品,为了简化,假设工厂只能生产一个商品、而用户也只能买一个商品
需求如下:
用户来购买,如果商品已经生产好了,则直接发货,完成交易用户来购买,如果商品还没生产好,让用户填写一个欠货单,待工厂生产好后,如果发现有欠货,则直接发货,完成交易
简简单单的一个需求,在多线程环境下就会出现隐患
单线程
先不考虑多线程情况,这个代码很好写,我们用一个ready变量标识是否生产完成,用一个unSupply变量标识是否有欠用户一个商品,代码如下
publicclassSerialShop{
privatevolatilebooleanready;//商品生产完成
privatevolatilebooleanunSupply;//是否欠用户一个商品
publicvolatilebooleandone;//交易完成
publicvoidsend(){//发货
System.out.println(sendtouser);
done=true;
publicvoidbuy(){
if(ready){//商品生产完成
send();//直接发货
return;
this.unSupply=true;//没有准备好则填写一个欠货单
publicvoidready(){
this.ready=true;//标识商品准备完成
if(this.unSupply){//如果发现有欠货单
send();//给用户发货
这时,我们简单跑一下
@Test
publicvoidbuyBeforeReady(){
buy();
ready();
@Test
publicvoidbuyAfterReady(){
ready();
buy();
结果无论先购买再生产完,还是生产完再购买,最终都会走到send方法,完成交易
多线程
上面的代码虽然简单,但在多线程下就会出现问题,用实际的情形描述一下
用户来购买发现商品没生产好,则开始准备填写欠货单,由于用户文盲,填写的很慢此时工厂恰好生产好了,标识已准备,但一看还没有欠货单,所以不发货用户刚刚填写完欠货单,没啥事就回家了最终,用户付完了钱,工厂也生产完毕,就是没有发货完成交易
画个时序图描述一下这个情景
时序图
因为多线程无法保证有序性,所以这种情况出现的概率很大,而一旦出现就是严重问题
用代码模拟一下这个场景:
publicclassUnsafeShop{
privatevolatilebooleanready;//商品生产完成
privatevolatilebooleanunSupply;//欠用户
publicvolatilebooleandone;//交易完成
publicvoidsend(){
System.out.println(sendtouser);
done=true;
publicvoidbuy()throwsInterruptedException{
if(ready){//准备好了
send();//直接发货
return;
Thread.sleep(100);//这里手动降低线程速度,为了重现场景
this.unSupply=true;//没有准备好则填写一个欠货单
publicvoidready()throwsInterruptedException{
this.ready=true;//标识商品准备完成
if(this.unSupply){//如果发现有欠货单
send();//给用户发货
@Test
文档评论(0)