1.线程的执行机制
线程分为用户线程 和 内核线程
内核线程就是系统级别的线程,与cpu逻辑处理器数量对应的
用户线程就是使用java代码创建的Thread对象
用户线程必须与内核线程关联(映射),才能执行任务
当用户线程多于内核线程时,内核线程就需要不停的上下文切换,使得多个用户线程都能得以执行
上下文会影响性能,消耗资源。
大量的创建用户线程,消耗用户线程,也会影响性能,消耗资源。
所以我们希望,创建合适数量的线程,不要频繁的创建新线程和销毁线程,希望创建的线程可以反复利用
我们就可以使用池化技术:线程池。
2.线程池的执行机制
线程池是jdk1.5中 JUC提供的一个工具
线程池的作用可以统一的创建,分配,管理,销毁线程。实现线程的复用。
3.线程池的应用
3.1拥有线程池
有两种方式,可以拥有线程池对象
手动创建线程池对象,需要传递7个参数
JUC提供了3个可以创建线程池的类,我们最常用的就是
ThreadPoolExecutor
通过JUC提供的工具类,快速获得线程池对象 (别人帮我们创建)
JUC提供了一个
Executors
工具类,该工具类提供了5个静态方法,可以快速获得对象
3.2手动创建线程池(7个参数)
有4种重载方法
①需要5个参数 ②需要6个参数 5+a ③需要6个参数 5+b ④需要7个参数
1. int corePoolSize : 核心线程数 , 池内线程数的下限,未达下限,优先创建新线程。达到下限,任务装入队列
2. int maximumPoolSize : 最大线程数。队列满,创建更多线程,直到达到上限。拒绝任务
3. long keepAliveTime : 线程空闲存活时间(数字)
4. TimeUnit unit : 配合keepAliveTime , 指定存活时间(单位)
5. BlockingQueue<Runnable> workQueue : 任务等待队列(阻塞队列)
ArrayBlockingQueue ,底层数组,适合指定长度
LinkedBlockingQueue,底层链表,适合无限长度
DelayQueue , 适合延迟(定时)任务
PriorityBlockingQueue 自认队列(元素自然有序,大小)
SynchronousQueue 同步队列,只能存一个元素
6. ThreadFactory threadFactory : 线程工厂,在线程池内部用来创建线程的。可以自定义
7. RejectedExecutionHandler handler : 拒绝策略,当任务队列满,线程达到上下且都忙碌,新任务被拒绝
juc提供了多种拒绝策略,也可以自定义
AbortPolicy 拒绝任务,并抛出异常
DiscardPolicy 拒绝任务,没有任何提示
DiscardOldestPolicy 拒绝最总加入等待瑞列的任务,
新任务加入队列
CallerRunsPolicy 拒绝任务,将任务交还给发起任务的线程
ThreadPoolExecutor pool=new ThreadPoolExecutor(5,10,5,
TimeUnit.MICROSECONDS,
new ArrayBlockingQueue(10));
pool.execute(Runnable); //执行Runnable任务
pool.submit(Runnable); //获得Future对象,可以知道线程是否执行完毕,但无法获得返回值
pool.submit(Callable); //获得Future对象,可以知道线程是否执行完毕,也可以获得返回值
future.isDone();//快速获得boolean结果,用来判断任务是否执行完毕
future.get();//获得任务执行的结果,如果还没有执行完毕,当前线程会处于等待状态
pool.getPoolSize();//获得线程数
pool.prestartAllCoreThreads() ;//预先创建核心数量的线程
pool.allowCoreThreadTimeOut(true);//设置核心数量的线程也可以超时被销毁
Queue q = pool.getQueue();//获得任务队列
q.size(); //等待执行的任务数量
q.clear();
q.add();
q.remove();