线程池
Callable 接口
extend Thread
implements Runnable
implements Callable 抛异常、有返回值
package com.xin;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author :小心仔
* @date :Created in 2021/11/6 14:57
* @description:
*/
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 只会执行一次
// FutureTask futureTask = new FutureTask(new MyThread());
// new Thread(futureTask,"AA").start();
// new Thread(futureTask,"BB").start();
// 执行两次
FutureTask futureTask1 = new FutureTask(new MyThread());
FutureTask futureTask2 = new FutureTask(new MyThread());
new Thread(futureTask1,"AA").start();
new Thread(futureTask2,"BB").start();
String result = String.valueOf(futureTask1.get());
System.out.println("值result:" + result);
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + "执行call()");
return 1024;
}
}
线程池及优势
处理过程中,将线程放入队列,线程数量超过最大数量会进行排队等候,等待其他线程执行完毕,队列中取出任务执行。
主要特点:线程复用、控制最大并发数、管理线程
线程池 自带常用的3个常用方式,生产环境不用
Executor executor = Executors.newFixedThreadPool(5);// 一池5线程 执行长期任务,性能好很多
Executor executor = Executors.newSingleThreadExecutor();// 一池 1线程 一个任务接一个任务
Executor executor = Executors.newCachedThreadPool();// 1池n线程 执行很多短的线程,异步小程序或负载较轻的服务器
生产环境不用,一般使用自己建的线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
5,
2L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
线程池配置合理线程数
CPU 密集型(后台进行大量判断if 处理的)
在多核CPU上才可能得到加速,单核不可能啦!!
一般配置尽可能少的线程数量
一般公式 CPU核数 + 1个线程的线程池
IO密集型 (大量访问redis/mysql)
IO 密集型并不是一直执行任务,应配置尽可能多的线程 如 CPU核数 * 2
参考2
阻塞系数 0.8 - 0.9 之间
参考公式 CPU核数 / (1 - 阻塞系数)
比如8核 : 8 / (1-0.9) = 80
线程池7大参数
corePoolSize 线程池常驻线程数
maximumPoolSize 线程池最大线程数 大于等于1
keepAliveTime 多余空闲线程存活时间
TimeUnit keepAliveTime 的单位
BlockingQueue 任务队列,被提交,未被执行的任务
ThreadFactory 工作线程连接工厂,一般用默认的
RejectedExecutionHandler 拒绝策略 ,队列满了,线程数大于等于线程池最大连接数
工作原理
线程池4大拒绝策略
AbortPolicy(默认) 抛出异常阻止程序运行
CallerRunsPolicy “”调用者运行“” 一种调节机制,不会抛弃任务、不会抛出异常、返回给调用者
DiscardOldestPolicy 抛弃队列中等待最久的任务,把当前任务加入队列再次提交当前任务
DiscardPolicy 直接丢弃任务,不予处理,也不抛弃异常。如果允许任务丢失,这是最好的一种方案
以上4个 均实现 RejectedExecutionHandler接口