线程池
首先我们要知道如何创建一个线程:
继承thread 重写run()
// 继承 Thread 类的自定义线程类 class MyThread extends Thread { @Override public void run() { System.out.println("Hello, I am a thread!"); } } public class Main { public static void main(String[] args) { // 创建自定义线程类的实例 MyThread myThread = new MyThread(); // 启动线程 myThread.start(); try { // 等待线程结束 myThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Main thread exiting."); }
实现runnable接口 重写run()
实现callable接口 重写run()
用线程池创建
// 创建一个固定大小的线程池,有3个线程 ExecutorService executor = Executors.newFixedThreadPool(3);
线程池是什么?
那得先说一下什么是线程,说白了就是cpu的时间片,我们用电脑开启了不同的功能,我们就是启用了多个线程,但是机器的瞬间我们人类的瞬间可不是一个概念,人类的瞬间可能是一秒,但这一秒对机器来说可能已经进行了成百上千次的线程切换.
然后再了解一下池化技术: 他是一个思想,比如我们在平时用对象时,需要进行频繁地创建和销毁,非常麻烦而池化技术就是先创建好几个常用的对象放到池子里,我们要用时,直接从池子里拿现成的就ok了,拿来就用,节省了频繁创建和销毁的开销,提高了复用性,也增强了性能
这样我们再来了解线程池是不是就好懂了?
说白了就是先把线程创建出来,要用的时候拿来就用.节省开销提高性能.
下面说一下线程池的组成
核心线程
阻塞队列
临时线程
当一个任务来时,看核心线程是否已满,如果满了,就会进入阻塞队列,阻塞队列也满了,就会临时创建一个线程来执行任务,临时线程过段时间没有任务处理后就会自动销毁,如果临时线程也满了,就会执行拒绝策略来对多余的线程进行处理
就像是你去银行办业务正常上班开三个窗口,窗口人满了坐后客气上等候一下,候客区也满了,就会新开几个窗口来处理业务,人不多了.临时窗口就下班回家了,如果以上的人都满了,就不接客了.
然后说一下线程池的几个参数:
corePoolSize: 核心线程池的大小
maximumPoolSize: 表示线程池所能创建的最大线程数(核心线程数+临时线程数)
keepAliveTime:空闲线程存活时间 (离下班点还有多少)
unit: keepAliveTime的实践单位
workQueue: 阻塞队列(候客区)
threadFactory: 创建线程的工程类 ,集中处理线程,方便维护
handler: 拒绝策略,任务满了会执行
-
-
AbortPolicy: 直接拒绝所提交的任务,并抛出RejectedExecutionException异常;
-
CallerRunsPolicy:只用调用者所在的线程来执行任务;
-
DiscardPolicy:不处理直接丢弃掉任务;
-
DiscardOldestPolicy:丢弃掉阻塞队列中存放时间最久的任务,执行当前任务
-