线程和线程池
什么是线程
线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
在java中如何创建线程
1.继承Thread类重写run方法
2.实现Runnable接口并实现run方法
3.实现Callable接口并实现call方法
4.使用线程池创建
class Thread1 extends Thread { @Override public void run() { super.run(); } } class Thread2 implements Runnable { @Override public void run() { } } class Thread3 implements Callable { @Override public Object call() throws Exception { return null; } } public class Test { public static void main(String[] args) { ExecutorService thread4 = Executors.newSingleThreadExecutor(); } }
四种方式的特点
- Thread:没什么好说的, 简单易懂
- Runnable:因为java具有单继承多实现的机制,所以可以优先使用这个方法
- Callable:这个方式开启线程会有一个返回值,而且调用的时候需要将线程包装成FutureTask任务才能运行新线程
- 线程池:使用线程池可以避免因为频繁的创建与销毁线程而带来的性能问题,不过如果线程池使用不当也会带来严重问题
线程池的种类
在java的Executors这个工具类中已经内置了几种已经被配置好的线程池,他们包括以下这几种
//单例线程池 ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); //缓存线程池 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); //固定数量线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1); //计划任务线程池 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
不过这几种线程池最终都会调用ThreadPoolExecutor的构造函数,换句话说,这几种线程池其实都是具有不同参数的ThreadPoolExecutor,所以只要我们看懂这个ThreadPoolExecutor,其余的也就可以看懂了
ThreadPoolExecutor参数说明
以下是jdk1.8版本的ThreadPoolExecutor的构造函数及其官方说明
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
corePoolSize – the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set(池中要保留的线程数,即使它们处于空闲状态,除非设置了allowCoreThreadTimeOut)
maximumPoolSize – the maximum number of threads to allow in the pool(池中允许的最大线程数)
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.( 当线程数大于核心数时,这是多余空闲线程在终止前等待新任务的最长时间。)
unit – the time unit for the keepAliveTime argument(keepAliveTime参数的时间单位)
workQueue – the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.( 用于在执行任务之前保留任务的队列。此队列将只保存execute方法提交的可运行任务。)
threadFactory – the factory to use when the executor creates a new thread
handler – the handler to use when execution is blocked because the thread bounds and queue capacities are reached(执行器创建新线程时使用的工厂
handler–由于达到线程边界和队列容量而阻止执行时要使用的处理程序)
当我们使用线程池的execute()或者submit()执行一个任务时,会直接交给corePoolSize来执行,当提交的任务大于corePoolSize时,将任务添加到workQueue中,等workQueue饱和时,会查看这个线程池的核心数是否已是最大,可是不是最大,就继续创建核心进行任务处理。若核心数已经是maximunPoolSize的大小,并且队列饱和,这时再添加任务时,会使用handler处理请求,默认的handler拒绝策略是AbortPolicy。
线程池的拒绝策略
AbortPolicy
丢弃任务并抛出RejectedExecutionException异常。
DiscardPolicy
丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。
DiscardOldestPolicy
丢弃队列最前面的任务,然后重新提交被拒绝的任务。
CallerRunsPolicy
由调用线程处理该任务
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步