java并发无锁多线程单线程示例详解.docx

java并发无锁多线程单线程示例详解.docx

  1. 1、本文档共11页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 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)

135****5541 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档