什么是高并发?

摘要:
总之,多线程可以理解为一种处理高并发的编程方法,即并发需要通过多线程实现。如果高并发处理不好,不仅会降低用户的体验,还可能导致系统停机、严重的OOM异常和系统停机。
一、什么是高并发

​ 高并发(High Concurrency)是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问收到大量请求(例如:12306的抢票情况;天猫双十一活动)。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求、数据库的操作等。

二、高并发的处理指标

高并发相关常用的一些指标有:响应时间、吞吐量、每秒查询率QPS、并发用户数
1、响应时间(Response Time)

响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间

2、吞吐量(Throughput)

吞吐量:单位时间内处理的请求数量。

3、每秒查询率QPS(Query Per Second)

QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。

4、并发用户数

并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。

三、高并发和多线程的关系和区别

“高并发和多线程”总是被一起提起,给人感觉两者好像相等,实则 高并发 ≠ 多线程

3.1、多线程

​ 多线程是Java的特性,因为现在cpu都是多核多线程的,可以同时执行几个任务,为了提高jvm的执行效率,Java提供了这种多线程的机制,以增强数据处理效率。多线程对应的是cpu,高并发对应的是访问请求,可以用单线程处理所有访问请求,也可以用多线程同时处理访问请求。
​ 在过去单CPU时代,单任务在一个时间点只能执行单一程序。之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程。虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行。
​ 后来发展到多线程技术,使得在一个程序内部能拥有多个线程并行执行。一个线程的执行可以被认为是一个CPU在执行该程序。当一个程序运行在多线程下,就好像有多个CPU在同时执行该程序。
​ 总之,多线程即可以这么理解:多线程是处理高并发的一种编程方法,即并发需要用多线程实现。

3.2、高并发

​ 高并发不是JAVA的专有的东西,是语言无关的广义的,为提供更好互联网服务而提出的概念。典型的场景,例如:12306抢火车票,天猫双十一秒杀活动等。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求,数据库的操作等。如果高并发处理不好,不仅仅降低了用户的体验度(请求响应时间过长),同时可能导致系统宕机,严重的甚至导致OOM异常,系统停止工作等。
​ 如果要想系统能够适应高并发状态,则需要从各个方面进行系统优化,包括,硬件、网络、系统架构、开发语言的选取、数据结构的运用、算法优化、数据库优化等……而多线程只是其中解决方法之一。

四、多线程并发技术

Java多线程编程将会涉及到如下技术点:
1、并发编程三要素
原子性:即一个不可再被分割的颗粒。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。
有序性:程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)
可见性:当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值。
2、 线程的五大状态
创建状态:当用 new 操作符创建一个线程的时候
就绪状态:调用 start 方法,处于就绪状态的线程并不一定马上就会执行 run 方法,还需要等待CPU的调度
运行状态:CPU 开始调度线程,并开始执行 run 方法
阻塞状态:线程的执行过程中由于一些原因进入阻塞状态比如:调用 sleep 方法、尝试去得到一个锁等等
死亡状态:run 方法执行完 或者 执行过程中遇到了一个异常
3、悲观锁与乐观锁
悲观锁:每次操作都会加锁,会造成线程阻塞。
乐观锁:每次操作不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止,不会造成线程阻塞。
4、线程之间的协作
线程间的协作有:wait/notify/notifyAll等
5、synchronized 关键字
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1)、修饰一个代码块:被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象
2)、修饰一个方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
3)、修改一个静态的方法:其作用的范围是整个静态方法,作用的对象是这个类的所有对象
4)、修改一个类:其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
6、CAS
CAS全称是Compare And Swap,即比较替换,是实现并发应用到的一种技术。操作包含三个操作数—内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。
CAS存在三大问题:ABA问题,循环时间长开销大,以及只能保证一个共享变量的原子操作。
7、线程池
如果我们使用线程的时候就去创建一个线程,虽然简单,但是存在很大的问题。如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。线程池通过复用可以大大减少线程频繁创建与销毁带来的性能上的损耗。

五、高并发技术解决方案

5.1、怎样提高系统的高并发能力?

1、静态资源结合CDN来解决图片文件等访问
2、分布式缓存:redis、memcached等。
3、消息队列中间件:activeMQ等,解决大量消息的异步处理能力。
4、应用拆分:一个工程被拆分为多个工程部署,利用dubbo解决多工程之间的通信。
5、数据库垂直拆分和水平拆分(分库分表)等。
6、数据库读写分离,解决大数据的查询问题。
7、利用nosql ,例如mongoDB配合mysql组合使用。
8、建立大数据访问情况下的服务降级以及限流机制等

免责声明:文章转载自《什么是高并发?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MFC用PostMessage传递消息案例:Oracle 10g RAC 集群无法启动下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

TCMalloc

http://code.google.com/p/gperftools/downloads/list   Tcmalloc通过preload或者直接动态链接的方式对malloc等内存分配和释放函数进行截获并提供服务。Tcmalloc提供接口主要涵盖malloc.h的接口   使用 要使用TCMalloc,只要将tcmalloc通过“-ltcmalloc”链...

BIO 是一个连接一个线程。,NIO 是一个请求一个线程。,AIO 是一个有效请求一个线程。

BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 AIO:异...

Kafka 异步消息也会阻塞?记一次 Dubbo 频繁超时排查过程

线上某服务 A 调用服务 B 接口完成一次交易,一次晚上的生产变更之后,系统监控发现服务 B 接口频繁超时,后续甚至返回线程池耗尽错误 Thread pool is EXHAUSTED。因为服务 B 依赖外部接口,刚开始误以为外部接口延时导致,所以临时增加服务 B dubbo 线程池线程数量。配置变更之后,重启服务,服务恢复正常。一段时间之后,服务 B...

golang 之GPM模型

1、Golang调度器的由来 2、Goroutine调度器的GMP模型及设计思想 3、Goroutine调度场景过程全图文解析 早期的单进程操作系统,面临2个问题: 1.单一的执行流程,计算机只能一个任务一个任务处理。 2.进程阻塞所带来的CPU时间浪费。 多进程/线程时代有了调度器需求: 进程拥有太多的资源,进程的创建、切换、销毁,都会占用很长的时间,...

epoll惊群原因分析

考虑如下情况(实际一般不会做,这里只是举个例子): 在主线程中创建一个socket、绑定到本地端口并监听 在主线程中创建一个epoll实例(epoll_create(2)) 将监听socket添加到epoll中(epoll_ctl(2)) 创建多个子线程,每个子线程都共享步骤2里创建的同一个epoll文件描述符,然后调用epoll_wait(2)等待事...

我的众安面试经历(题库)

摘要: 原创出处 https://www.cnblogs.com/lossingdawn/p/9569524.html「痞子姜」欢迎转载,保留摘要,谢谢! 面试众安在线背景:两年java,面中级开发 首先,是两道编程题,笔试 1、斐波那契数列,f(n)=f(n-1)+f(n-2),n足够大,获取f(n)的值 ~ 2、一个足够大的数组,有10E+个数字,怎么...