JDK线程池

线程池五个状态
RUNNING:初始状态
SHUTDOWN:不再接受新的任务,会将阻塞队列中的任务处理完
STOP:不再接受新的任务,中断正在执行的任务,抛弃阻塞队列中的任务
TIDYING:任务全部执行完毕,活动线程为0
TERMINATED:终结状态

构造方法

线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行任务
当线程数达到corePoolSize并没有线程空闲,这时再加入任务,会被加入workQueue队列排队,直到有空闲的线程
如果队列选择了有界队列,那么任务超过了队列大小时,会创建maximumPoolSize - corePoolSize数目的线程来救急
如果线程到达maximumPoolSize仍有新任务,这时会执行拒绝策略
拒绝策略jdk提供了4种实现
AbortPolicy:让调用者抛出RejectedExecutionException异常(default)
CallerRunsPolicy:让调用者运行任务
DiscardPolicy:放弃本次任务
DiscardOldestPolicy:放弃队列中最早的任务,本任务取而代之
/**
 * 任务
 * 核心线程处理 -> 核心线程都在忙,放入任务阻塞队列 -> 任务阻塞队列满了交给非核心线程处理 -> 拒绝策略
 * 核心线程不会销毁,非核心线程干完活儿会有生存时间
 *
 * corePoolSize核心线程数量为 2
 * maximumPoolSize最大线程数量为 3, 即有一个是非核心线程
 * keepAliveTime非核心线程的空闲生存时间为 1分钟,(空闲时间超过 1分钟, 会进行销毁)
 * workQueue没有空闲的核心线程时(任务数 > 核心线程数), 多余的任务放到 ArrayBlockingQueue 队列中, 容量为 2
 */
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,3,1,TimeUnit.MINUTES,new ArrayBlockingQueue<>(2));

Executors类

// Executors类提供了一些static方法来创建各种用途的线程池

// 只有核心线程
// 任务阻塞队列是无界的
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}

// 只有非核心线程
// 非核心线程的空闲生存时间是60s
// SynchronousQueue阻塞队列(这个队列没有容量,插入的时候会阻塞,直到另一个线程来取,才停止阻塞)
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}

// 只有一个核心线程
// 使用场景:希望多个任务排队执行
// Unlike the otherwise equivalent {@code newFixedThreadPool(1)} the returned executor is
// guaranteed not to be reconfigurable to use additional threads.
public static ExecutorService newSingleThreadExecutor() {
	// 不直接返回ThreadPoolExecutor对象,避免出去之后可以强转为ThreadPoolExecutor,调用它的特有方法
	// 装饰器模式(限制了ThreadPoolExecutor类中一些特有方法的暴露,只有ExecutorService中定义的方法)
    return new FinalizableDelegatedExecutorService
    (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
public static void main(String[] args) throws InterruptedException {
    // 这个队列是没有容量的
    SynchronousQueue<Integer> integers = new SynchronousQueue<>();
    new Thread(() -> {
        try {
            log.debug("putting 1");
            integers.put(1); // 会阻塞放不进去,直到有个线程来从队列中拿元素
            log.debug("1 putted");

            log.debug("putting 2");
            integers.put(2);
            log.debug("2 putted");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    },"t1").start();

    TimeUnit.SECONDS.sleep(1);
    // 取元素
    new Thread(() -> {
        try {
            log.debug("taking 1");
            integers.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    },"t2").start();
    TimeUnit.SECONDS.sleep(1);
    // 取元素
    new Thread(() -> {
        try {
            log.debug("taking 2");
            integers.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    },"t3").start();
}
// 使用场景:希望多个任务排队执行
// 出现了异常,线程池会新建一个线程,保证线程池的正常工作
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(() -> {
    log.debug("1");
    int i = 1 / 0; // 新建一个线程,后面的任务会正常执行
});
pool.execute(() -> log.debug("2"));
pool.execute(() -> log.debug("3"));

提交任务的一些方法

void execute(Runnable command); // Executor接口
<T> Future<T> submit(Callable<T> task); // ExecutorService接口
// 提交任务集合
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks); // ExecutorService接口
// 提交任务集合,只要有一个任务执行完毕了,就会取消掉其他任务
// 方法的返回结果就是那个任务的返回结果
<T> T invokeAny(Collection<? extends Callable<T>> tasks); // ExecutorService接口

关闭线程池

// 不是RUNNING状态的线程池,都会返回TRUE
boolean isShutdown();

// 执行后,线程池状态变为SHUTDOWN
// 调用此方法不会阻塞调用该方法的线程的执行
// 主线程不会等线程池中的线程执行完毕才执行shutdown()后面的代码
void shutdown(); // ExecutorService接口

// 执行后,线程池状态变为STOP
// 用interrupt的方式打断正在执行的任务
// 返回任务队列中的任务
List<Runnable> shutdownNow(); // ExecutorService接口

// 调用shutdown()后,主线程不会等线程池中线程结束,如果想在线程池TERMINATED后做些事情,可以使用此方法等待
// Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs
// or the current thread is interrupted, whichever happens first.
boolean awaitTermination(long timeout, TimeUnit unit); // ExecutorService接口

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值