一:多线程的介绍以及使用
其实,在java中多线程的使用是一个项目走向规模化的重要转折点(这里的使用是指应项目需求而必须去使用多线程)。很多时候我们对于多线程的使用还是停留在常用的框架提供的工具类,比如说jdk自带的Executor以及一些成熟框架的线程池框架等。这里我们将花费一个系列的时间来探讨一下java的多线程的秘密。
二:多线程涉及的基本的概念
这里我们将java多线程涉及的一些概念:
(1)线程和进程的概念以及区别
进程:每一个应用运行都是一个进程,进程与进程之间不共享资源(这句很重要)。
线程:线程是指进程应用中每一个产生的一次操作甚至一次访问,进程之间资源共享(这句也很重要)。
说明:这里为什么将这俩个概念单独提取出来说明呢?
原因:一个项目的功能一旦扩展到很大,设计到功能很多时,我们至少需要将项目进行集群处理,这个时候项目就有一 个进程变成多进程,项目中多线程的复杂度也就变成了O*N。更不用说SOA和微服务架构了。
(2)多线程的产生(并发-并行)
并发:共性线程的同时运行,线程之间相互关联,相互影响(这是区别),比较典型的场景就是对于同一个方法进行多线程 执行。
并行:非共性的线程的同时运行,线程之间没有关联和影响,一般而言对于一个系统,同一个时间不同用户在处理不同模块
说明: 总的而言,java中的多线程就是基于这2中场景而产生的。一般的技术栈中都是尝试对于并发的的多线程的处 理,比如说springboot框架中的异步线程等,但是实际上在spring框架对于并行的场景处理的多线程都是封装在 spring内部中,因此在以后的章节中,多线程如果没有说明都是指的是对于并发的处理。
衡量系统多线程处理能力的的标准概念:
QPS(TPS):秒级别处理请求的数量
并发量:系统在同一个时间内处理请求的数量。
(3)多线程和线程池的概念
多线程:系统在同一时间或者同一个时间段内处理请求(如java中Thread等)。
线程池:封装的多线程的框架(如springboot中的异步线程池)。
说明:在很多时候,我们认为用到了线程池就是默认是多线程,这种说法是没有问题的,但是对于我们深入理解还 是需要区别。
三:线程的状态
java中的线程的技术栈都是基于线程产生的,那么我们就需要了解什么是线程,线程的基本状态等。线程的基本概念就不用说了。
(1)线程的基本状态
一般我们都默认java中线程拥有5中基本状态:新建(new Thread() ...),就绪( .start() ) ,运行( .run() ) ,阻塞 ( . sleep()...),结束等。
这是网上一幅图,其中他把“等待”也作为一个状态了,很多时候我们把这个状态归纳到阻赛中。
(2)线程状态的转变
新建:新建一个线程,通过继承Thread或者实现Runable接口,然后new一个新的实例出来(这个实现线程的3中方式就不用说 明了吧)。
就绪:线程调用.start()方法,表示该线程具有竞争cpu执行权的权限。
运行:调用.run()方法,表示进入该线程执行线程内的方法。
阻塞:通用的一种说法就是由于I/O问题导致线程进入挂起状态。在java中.sleep(),.wait()方法等都可以使线程挂起(后面会具 体说明这些方法的使用)。
如果我们使用自定义线程的方法,在线程结束后一定要关闭线程,否则一定会导致 cpu的占用蹭蹭上涨,切记。
由单线程转向多线程的一些基本概念就说这些。下一节,我们就来谈谈多线程之间的线程协作。