1、线程池参数
2三种自带的线程池
3、自定义一个线程池
ThreadPoolExecutor service4=new ThreadPoolExecutor(10, 20, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));//自定义线程池,核心线程和非核心线程都是10 for(int i=0;i<100;i++){ service4.execute(new MyRunnable(i)); }
执行结果
到第30的时候就出错了,因为核心线程+非核心线程+队列总共容纳30个任务,现在要执行100次,所以就会出错。
为什么不是后面i的值不是有序的,因为提交优先级是:核心线程>队列>非核心线程
而执行优先级是:核心线程>非核心线程>队列
4、拒绝策略
提交优先级源码:
执行优先级源码
5、流程图
6、用户线程和内核线程区别
用户线程(ULT):指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统的核心,应用进程利用线程库创建、同步、调度和管理线程函数来控制用户线程。另外,因为用户线程是由应用进程利用线程库创建和管理,不依赖于操作系统核心,不需要进行用户态与核心态的切换,速度快,操作系统的内核不知道多线程的存在,因此一个线程阻塞将使得整个进程包括其所有线程阻塞
内核线程(KLT):线程的所有管理操作都是由操作系统内核完成的。内核保存线程的状态和上下文信息,当一个线程执行了引起阻塞的系统调用时,内核可以调度进程的其他线程执行,在多处理器系统上,内核可以分派属于同一进程的多个线程在多个处理器上运行,提高进程执行的并行度。由于需要内核完成线程的创建、调度和管理,所以和用户级线程相比这些操作要慢得多,但仍比进程创建和管理操作快的多
7、JVM确实是使用内核级线程,并且内核线程与Java-Thread是1:1的映射关系。
8、适用场景:
单个任务处理时间比较短
需要处理的任务量很大
9、好处:
重用存在的线程,减少线程创建、消亡的开销,提高性能
提高响应速度,当任务到达时,任务不需要等线程创建就立即执行
提高线程的可管理性,如果无限制的创建,不仅会消耗资源,还会降低系统的稳定性,使用线程池可以统一的分配,调优和监控
10、线程池总体步骤
1)任务先进入核心线程池执行
2)若核心线程池已满,则任务进入队列
3)若队列已满,则启动非核心线程执行任务,新任务填充到队列
4)若非核心线程也满了(队列也填充满),此时再进入任务则执行拒绝操作
11、线程池的5种状态