线程池
一、
public class ThreadTest {
public static ExecutorService service = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
/**
* 1)、继承Thread
* Thread01 thread01 = new Thread01();
* thread01.start();
* 2)、实现 Runnable接口
* new Thread(new Runnable01()).start();
* 3)、实现 Callable接口 + FutureTast (可以拿到返回结果。处理异常)
* FutrueTast<Integer> futureTask = new FutureTask<>(new Callable01());
* new Thread(futureTask).start
* 等待线程执行完获取结果
* Integer n = futureTask.get();
* 4)、线程池
* 可以将执行任务交给线程池执池
*
* 区别:
* 1、2不能得到返回值,3可以得到返回值
* 1、2、3在资源利用上是不能控
* 4、可控资源
*
*/
//我们以后在业务代码里面,以上三种启动方式都不用【将所有线程的异步任务交给线程池】
service.execute(new Runnable01());
}
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("Thread01当前线程号 -> " + Thread.currentThread().getId());
int n = 10 /5;
System.out.println(n);
}
}
public static class Runnable01 implements Runnable {
@Override
public void run() {
System.out.println("Runnable01当前线程号 -> " + Thread.currentThread().getId());
int n = 10 /5;
System.out.println(n);
}
}
public static class Callable01 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Runnable01当前线程号 -> " + Thread.currentThread().getId());
int n = 10 /5;
return n;
}
}
}
二、线程池的分类
2.1 Executors.newCacheThreadPool():可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中,缓存型池子通 常用于执行一些生存期很短的异步型任务
2.2 Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程
2.3 Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
2.4 Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行
三、线程池参数
1)、corePoolSize :指定线程池的线程数
2)、maximumPoolSize :线程池最大线程数量
3)、keepAliveTime :空闲时间,是指当前的线程数量大于corePoolSize时,多余空闲线程的存活时间
4)、 workQueue:任务队列,存放被提交但尚未被执行的任务
5)、threadFactory : 创建一个新线程时使用的工厂,一般默认即可
6)、handler 拒绝策略,当任务太多来不及处理,怎么样拒绝任务
7)、unit:空闲线程存活时间单位
四、线程池的运行过程
1、线程池的创建,准备corePoolSize数量的线程,准备接收任务
2、新的任务进来,用corePoolSize准备好的空闲线程执行
a、corePoolSize满了,就将再进来的任务放到阻塞队列中,空闲的corePoolSize就会自己去队列中领取任务
b、阻塞队列满了,就开启新线程执行,最大只能开到maximumPoolSize指定数量
c、maximumPoolSize都执行好了,maximumPoolSize减corePoolSize数量的空闲线程会在指定keepAliveTime 后自动销毁,最终保持corePoolSize 大小
d、如果线程数开到maximumPoolSize 的数量,还有新任务进来,就会使用指定handler 拒绝策略进行处理
3、所以线程都由threadFactory 创建
五、线程池的创建方式
1、Executors
2、ThreadPoolExecutor