前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发问题

并发问题

作者头像
付威
发布2018-12-05 11:37:57
6920
发布2018-12-05 11:37:57
举报

并发问题

在编程的时候我们经常会碰到并发的问题,如果处理不好很有可能造成业务数据的错误。我们思考,到底什么是并发问题? 简单的来说我们可以把并发问题归纳为:未写入而先读取 带来的问题。

我们用最简单的取钱的模型来描述这个问题:

compare
compare

在①②③④ 这个几个步骤中,①②和③④分别是两个独立的过程,如果执行的顺序是 ①③②④,这样就会带来最终余额为负的现象,这个就是一个简单的并发问题。

我们可以用代码简单的模拟这个问题:

代码语言:javascript
复制
public class AppTest {
	private int count = 0;
	public static void main(String[] args) {
		long ts = System.currentTimeMillis();
		AppTest app = new AppTest();
		List<Thread> tList = new ArrayList<>(500);
		
		for (int i = 0; i < 10000; i++) {
			Thread thread = new Thread(() -> {
				for (int m = 0; m < 1000; m++) {
					app.count();
				}
			});
			tList.add(thread);
		}
		//启动线程
		for (Thread t : tList) {
			t.start();
		}
		//等待所有线程执行完
		for (Thread t : tList) {
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println(app.count);
		long tend = System.currentTimeMillis();
		System.out.println(tend-ts);
	}
	
	private  void count() {
		count++;
	}
}

上述代码执行结果: 9997990(结果具有不确定性,此次结果就偶然一次结果),耗时:3378

造成这个结果的原因就是,在多线程执行的过程中,count的值还没有来得及写入内存,另一个线程就已经把count的读取,就导致count少一次count++运算。

解决并发

既然我们已经知道并发问题,如何解决? 对于并发的解决思路是:保证读取的时候,写入已经完成。具体方法有两种,分别是锁和CAS操作。

使用锁 synchronized

修改count()方法:

代码语言:javascript
复制
	private synchronized void count() {
		count++;
	}

运行结果:10000000 耗时:4176

锁的方法导致性能下降很多。

使用CAS操作

把int类型的count换成AtomicInteger类型

代码语言:javascript
复制
private AtomicInteger count = new AtomicInteger();

private void count() {
		count.addAndGet(1);
	}

修改上述两出代码得到运行结果:10000000 耗时:3305

(本文完)

作者:老付 如果觉得对您有帮助,可以下方的订阅,或者选择右侧捐赠作者,如果有问题,请在捐赠后咨询,谢谢合作 如有任何知识产权、版权问题或理论错误,还请指正。 自由转载-非商用-非衍生-保持署名,请遵循:创意共享3.0许可证 交流请加群113249828:点击加群 或发我邮件 laofu_online@163.com

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 并发问题
  • 解决并发
    • 使用锁 synchronized
    • 使用CAS操作
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档