多线程Review-926-01

发布时间 2023-09-26 20:44:57作者: qd372502

一、进程与线程

1、进程:

①电脑管家等 软件 我们运行的应用程序

②在内存中正在运行的程序

2、线程:

①进程中的一个最小执行单元。一个进程最少得有一个线程

②软件中的每一个功能,如电脑管家中的清理垃圾、杀毒、软件搜索

二、线程的创建方式

1、继承Thread类    :

优点——代码清晰,编写简单。

缺点——单继承、继承局限性(不想继承其中所有功能。单一职责原则、接口隔离原则),线程不能返回值

2、实现Runable接口   :

优点——多实现,更灵活,可以使用匿名内部类、lambda表达式简单的创建。

缺点:编写复杂,线程不能返回值

3、实现Callable接口:

优点——线程有返回值,可以使用future对象的get方法对线程进行结果的接收。需要获取多个线程返回值并利用时可以使用这种方式。

缺点:编写复杂,需要实现Callable<返回值泛型>、FutureTask<返回值泛型> 对象参数callable,new Thread(future).start()

4、线程池:

优点:

资源管理、提高性能、限制并发数量、任务排队、线程复用、监控和管理

缺点:

资源消耗、线程间通信复杂性、不当使用可能导致问题、难以控制任务执行时间、不适用于所有场景:并不是所有的应用场景都适合使用线程池。例如,对于一些需要严格控制线程生命周期和资源的应用,手动管理线程可能更合适。

重点——线程池:

工作流程:

1、当有任务提交时,判断,是否达到核心线程数量?没达到,创建一个工作线程来执行任务。

2、工作队列是否已满?没满,则将新提交的任务存储在工作队列中。

3、是否达到线程池最大数量?没达到,则创建一个新的工作线程来执行任务

4、最后,执行拒绝策略来执行这个任务

图示1(任务提交工作流程):

 

 图示2(任务提交工作流程):

 线程池核心参数

1、核心线程数

2、最大线程数

3、阻塞队列

4、线程保活时间

5、临时线程保活时间单位 TimeUnit

6、线程工厂

7、拒绝策略:

AbortPolicy:丢弃任务并抛出RejectedExecutionException异常 (默认)

DiscardPolicy:丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。

DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。

CallerRunsPolicy:由调用线程处理该任务

你一般是怎么来设置这些参数?①具体是根据实际业务场景来的②核心线程数③最大线程数④队列长度⑤保活时间

1. **具体是根据实际业务场景来的:** 线程池参数的设置需要综合考虑系统的负载、性能需求、资源限制以及线程创建和销毁成本等因素。在实际应用中,通常需要进行性能测试和调优,以找到最佳的参数配置。同时,监控线程池的运行状态也是很重要的,以及时调整参数以适应变化的负载情况。

2. **核心线程数(Core Pool Size):** 这是线程池中保持活动状态的最小线程数。它应该根据系统的预期负载来设置。如果系统的负载通常较低,可以将核心线程数设置较低,以减少资源消耗。如果系统的负载通常较高,可以设置较高的核心线程数,以提高响应性。

3. **最大线程数(Maximum Pool Size):** 这是线程池中允许的最大线程数。它应该根据系统的最大负载来设置。如果系统需要处理高并发请求,可以设置较高的最大线程数,以确保有足够的线程可用。但要小心不要设置得太高,以避免消耗过多的系统资源。

4. **队列长度(Queue Capacity):** 队列用于存储等待执行的任务。队列长度应该根据系统的负载特点和内存限制来设置。如果系统的请求处理速度大于线程执行速度,可以选择一个相对较大的队列长度,以平滑负载峰值。但要注意,队列长度过大可能会导致内存消耗增加。如果系统的请求处理速度与线程执行速度相近,可以选择较小的队列长度,以减少内存消耗。

5. **保活时间(Keep-Alive Time):** 当线程池中的线程数量超过核心线程数时,多余的空闲线程会在一定时间内被销毁以减少资源占用。保活时间应该根据线程的创建成本和线程池的响应时间需求来设置。如果线程的创建成本较高,可以将保活时间设置较长,以减少线程的频繁创建和销毁。如果需要更快的响应时间,可以将保活时间设置较短,以确保线程池能够更快地响应新任务。

怎么参考设置核心线程数的具体值?

核心线程:
CPU密集型:核心线程数=CPU核心数(或 核心线程数=CPU核心数+1)。
I/O密集型:核心线程数=2*CPU核心数(或 核心线程数=CPU核心数/(1-阻塞系数))。

IO密集CPU核数X 2
CPU密集: CPU核数 +1

最大线程:
CPU密集型应用,最大线程设置为 N+1。
IO密集型经验应用,最大线程设置为 2N+1 (N为CPU数量)。

线程池创建了,里面有线程吗?

-没有,任务提交过来,创建线程去执行

如果提交任务数到达了最大线程数,请问,这个核心线程是多少?

-不变。当提交任务数达到最大线程数时,核心线程数的概念不再适用,线程池会继续创建非核心线程来处理任务,直到达到最大线程数的限制。核心线程数只在初始创建线程时和在非核心线程空闲一定时间后进行保活时起作用。