Java线程池----mark

本文详细介绍了Java线程池的基本架构及其组成部分,包括Executor、ExecutorService、ScheduledExecutorService等核心接口与类。并通过实例演示了如何创建线程池并设置其参数,如corePoolSize、maximumPoolSize等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近温习了Java线程池相关的知识,感觉太久没看,都忘了,特此记录。

1.   Excutor:   java线程池的顶层接口,提供了execute(Runnable r)方法。

2.   ExcutorService:  继承自execute方法的一个接口,是为Executor服务的,用于进行线程的提交(submit),执行(invokeAll,invokeAny)等操作。

3.   AbstracExecutorService:   实现了ExecutorService的一个虚函数,主要是对ExecutorService的方法提供默认实现。

4.   ThreadPoolExcutor:    线程池,继承自AbstractExecutorSerice虚函数,主要方法有: 线程池创建,线程池corePoolSiez,maximumPoolSize等参数的设置,线程池状态变化等。

5.    ScheduledExecutorService:  继承自ExecutorService接口,提供了延迟和周期性执行的ExecutorService。

6.    ScheduledThreadPool:   实现了ScheduledExecutorService接口,相当于一个提供延迟和周期执行的线程池。

7.     Executors:   是一个静态工厂类,通过静态工厂方法返回ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 等类的对象。


上面是Java线程池的基本的架构:下面我们通过例子来学习Java线程池相关知识点。

1. 创建一个Java线程池,首先查看Java线程池的构造函数:

    /**
     * Creates a new {@code ThreadPoolExecutor} with the given initial
     * parameters.
     *
     * @param corePoolSize the number of threads to keep in the pool, even
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * @param maximumPoolSize the maximum number of threads to allow in the
     *        pool
     * @param keepAliveTime when the number of threads is greater than
     *        the core, this is the maximum time that excess idle threads
     *        will wait for new tasks before terminating.
     * @param unit the time unit for the {@code keepAliveTime} argument
     * @param workQueue the queue to use for holding tasks before they are
     *        executed.  This queue will hold only the {@code Runnable}
     *        tasks submitted by the {@code execute} method.
     * @param threadFactory the factory to use when the executor
     *        creates a new thread
     * @param handler the handler to use when execution is blocked
     *        because the thread bounds and queue capacities are reached
     * @throws IllegalArgumentException if one of the following holds:<br>
     *         {@code corePoolSize < 0}<br>
     *         {@code keepAliveTime < 0}<br>
     *         {@code maximumPoolSize <= 0}<br>
     *         {@code maximumPoolSize < corePoolSize}
     * @throws NullPointerException if {@code workQueue}
     *         or {@code threadFactory} or {@code handler} is null
     */
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

可以看到创建一个线程池需要的所有参数: corePoolSize,maximumPoolSize,workQueue,keepAliveTime,threadFactory,handler;

下面通过例子来学习:

1.   当创建的线程超过了线程池能提供的服务数量之后:并且采用默认的拒绝策略:   AbortPolicy此时会产生什么情况呢?

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Test{
	public static void main(String[] args0) throws InterruptedException{
		/**
		 * corePoolSize:   核心池的大小。就是现在线程池包含的线程的数量
		 * maximumPoolSize:   最大线程池线程数量: 就是这个线程池最多能包含多少个线程
		 * KeepAliveTime:   通常与allowCoreThreadTimeout连用    其中allowCoreThreadTimeout: 是否允许线程在空闲时存活  默认false   
		 * 				   keepAliveTime: 指的是当allowCoreThreadTimeout为true的时候,能够忍受线程空闲的时间
		 * unit:     空闲时间的单位
		 * workQueue:是一个BlockingQueue类型,是一个阻塞队列,当当前线程超过它的容量的时候就是进入到workQueue
		 * threadFactory:   线程创建工厂
		 * handler:   线程拒绝策略句柄
		 */
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 0, TimeUnit.SECONDS,  new ArrayBlockingQueue<Runnable>(3));
		//上面我们创建了一个线程池,并且线程中的ThreadFactory采用的是默认的工厂方式           为了后面方面我们暂时使用了ThreadPoolExecutor的默认拒绝策略      AbortPolicy
		//创建了一个阻塞队列,队列大小为5
		
		for(int i=0;i<10;i++){
			ThreadTest test = new ThreadTest(i+"");
			threadPoolExecutor.execute(test);
			Thread.sleep(100);
			//System.out.println(threadPoolExecutor.getPoolSize());
		}
		threadPoolExecutor.shutdown();
		System.out.println(threadPoolExecutor.isShutdown());
	}
}
class ThreadTest implements Runnable{
	String name = "";
	public ThreadTest(String temp){
		this.name = temp;
	}
	public void run() {
		System.out.println(name+"线程正在开始执行");
		try {
			///模拟线程正在执行任务
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(name+"线程执行完成");
	}
}
我们创建了十个线程,但是线程池的maximumPoolSize和BlockingQueue之和为8,采用abortPiolicy策略,那么一定会抛出异常。可以从结果中看出,当线程
0线程正在开始执行
1线程正在开始执行
5线程正在开始执行
6线程正在开始执行
7线程正在开始执行
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task ThreadTest@55f96302 rejected from java.util.concurrent.ThreadPoolExecutor@3d4eac69[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
<span style="white-space:pre">	</span>at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(Unknown Source)
<span style="white-space:pre">	</span>at java.util.concurrent.ThreadPoolExecutor.reject(Unknown Source)
<span style="white-space:pre">	</span>at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
<span style="white-space:pre">	</span>at Test.main(Test.java:23)
0线程执行完成
2线程正在开始执行
1线程执行完成
3线程正在开始执行
5线程执行完成
4线程正在开始执行
6线程执行完成
7线程执行完成
2线程执行完成
3线程执行完成
4线程执行完成
自己画了一个图,来表示这个过程,但是线程执行时间不同,进程图调用过程图就不同了。

从图和上面的日志可看出: 执行到异常的时候就不再执行了。而是继续完成pool和Queue里面的线程。


后续策略待续

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比和丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)和IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”和“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项和项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全和寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量和数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储和显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值