还不打算结束一天的工作吗?

Java

Java中高级高并发与多线程系列(一):高并发与多线程有什么关系

2021年04月07日 10:12:21 · 本文共 1,198 字阅读时间约 4分钟 · 3,567 次浏览
Java中高级高并发与多线程系列(一):高并发与多线程有什么关系

首先声明,本系列文章分享都是我自己的学习理解以后,原创手敲,可能包含错误的观点和理解,仅供参考,如遇错误的地方欢迎指正。

很多教程一上来就讲计算机原理,搞一堆 CPU 是怎么运行的,什么是进程、线程,然后就开始将学术内容,作为新手肯定有疑问,我的代码里并没有使用线程呀,为啥一说高并发就开始讲多线程?

兴趣是最好的老师,我也很好奇,高并发和多线程有什么关系,我又没新建线程去运行,为啥到处要讲多线程?所以我的开篇就是探究为什么要学习多线程,怎么高并发就是多线程了。

一次访问发生了什么

首先,浏览器输入网址 DNS 解析和 HTTP 握手和监听端口啥的咱就不说了,不是本文的重点,默认请求已经路由到了我们的程序开始处理请求。

当一个请求到达我们的程序,框架会将请求映射成 HttpRequest 对象,万物皆对象,然后框架从线程池中拿出一个线程让这个线程去处理这次请求,使用线程池是为了节省资源,就算没有线程池也会新建一个线程去执行,因为创建线程和销毁线程都需要宝贵的资源,因为请求可能会有很多,如果一个一个处理让其他请求等待那就太浪费了,我们现在可是多核心多线程的 CPU ,可以同时处理很多事,请求同时处理各自处理各自的。

如果线程很少,操作我们的数据库,都是处理完一个,再处理一个,很和谐,数据取出处理放回,好像没什么问题,但是如果线程很多的话,会怎么样呢。

高并发与多线程关系

上面我们知道在 Java 的世界里万物皆对象,每个请求进来就是一个对象,会拿一个线程去执行处理这个请求,如果这个请求执行的代码都一样,比如经典的秒杀,大家都去抢一个商品,所以这些线程执行的代码逻辑都一样,都是要取同一个商品,减同一个商品的库存,这个时候就把高并发变成了多线程,因为每个线程都要修改同一个资源,问题就会出现在这里,为了更好地理解,我在下面画了个模拟图,只是模拟说明:

高并发.jpg

综上所述,很多软件公司都要求有多线程编程经验也是因为这个原因,一旦并发量上来,就会造成多线程修改同一个资源,如果协调不好,这个资源可能就会出问题。

多线程会出啥问题

虽然各个线程看上去好像是在同时执行的,但底层并不是同时执行,CPU 数量是有限的,它在同一时刻只能处理一个任务,只不过 CPU 非常的快,为了照顾各个线程都能被执行处理,所以 CPU 采用时间分片的方式对各个线程进行轮换执行,给人造成的错觉好像是一起在执行,其实只不过是 CPU 切换的快而已,这就造成一个问题,线程并不知道执行到哪里就被踢出 CPU 了,等回来的时候还是继续从被踢出 CPU 的那里执行。

假设:

  1. 线程A 得到 CPU 的调度开始运行,拿到商品库存为1,然后被调度踢出 CPU 了,先挂起等待;

  2. 线程B 得到 CPU 的调度开始运行,也拿到商品库存为1,然后被调度踢出 CPU 了,先挂起等待;

  3. 线程A 得到 CPU 的调度开始运行,执行商品库存-1操作,现在数据库里的库存是0,然后被调度踢出 CPU 了;

  4. 线程B 得到 CPU 的调度开始运行,同样执行商品库存-1操作,现在数据库里的库存是-1;

你会发现,可能好几个人都抢到了订单,而库存被减成了负数,还能有人下单成功,这就是比较常见的多线程产生的问题。所以学习多线程编程非常重要。


商业用途请联系作者获得授权。
版权声明:本文为博主「任霏」原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://www.renfei.net/posts/1003491
评论与留言

以下内容均由网友提交发布,版权与真实性无法查证,请自行辨别。

微信搜一搜:任霏博客