并发编程—7.2线程池基础
Posted codetree
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发编程—7.2线程池基础相关的知识,希望对你有一定的参考价值。
目录
1.什么是线程池?为什么要用线程池?
- 降低资源的消耗。线程的创建和销毁
- 提高响应速度。线程的创建时间为T1,执行时间T2,销毁时间T3,免去T1和T3的时间
- 提高线程的可管理性。
2.实现一个我们自己的线程池
package com.xiangxue.ch6.mypool;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
*@author Mark老师 享学课堂 https://enjoy.ke.qq.com
*
*类说明:自己线程池的实现
*/
public class MyThreadPool2 {
// 线程池中默认线程的个数为5
private static int WORK_NUM = 5;
// 队列默认任务个数为100
private static int TASK_COUNT = 100;
// 工作线程组
private WorkThread[] workThreads;
// 任务队列,作为一个缓冲
private final BlockingQueue<Runnable> taskQueue;
private final int worker_num;//用户在构造这个池,希望的启动的线程数
// 创建具有默认线程个数的线程池
public MyThreadPool2() {
this(WORK_NUM,TASK_COUNT);
}
// 创建线程池,worker_num为线程池中工作线程的个数
public MyThreadPool2(int worker_num,int taskCount) {
if (worker_num<=0) worker_num = WORK_NUM;
if(taskCount<=0) taskCount = TASK_COUNT;
this.worker_num = worker_num;
taskQueue = new ArrayBlockingQueue<>(taskCount);
workThreads = new WorkThread[worker_num];
for(int i=0;i<worker_num;i++) {
workThreads[i] = new WorkThread();
workThreads[i].start();
}
Runtime.getRuntime().availableProcessors();
}
// 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器决定
public void execute(Runnable task) {
try {
taskQueue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁
public void destroy() {
// 工作线程停止工作,且置为null
System.out.println("ready close pool.....");
for(int i=0;i<worker_num;i++) {
workThreads[i].stopWorker();
workThreads[i] = null;//help gc
}
taskQueue.clear();// 清空任务队列
}
// 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数
@Override
public String toString() {
return "WorkThread number:" + worker_num
+ " wait task number:" + taskQueue.size();
}
/**
* 内部类,工作线程
*/
private class WorkThread extends Thread{
@Override
public void run(){
Runnable r = null;
try {
while (!isInterrupted()) {
r = taskQueue.take();
if(r!=null) {
System.out.println(getId()+" ready exec :"+r);
r.run();
}
r = null;//help gc;
}
} catch (Exception e) {
// TODO: handle exception
}
}
public void stopWorker() {
interrupt();
}
}
}
3.JDK中的线程池和工作机制
3.1 线程池的创建
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
各个参数含义
+ corePoolSize
核心运行的poolSize,也就是当超过这个范围的时候,就需要将新的Thread放入到等待队列中了
+ maximumPoolSize? ?线程池最大容量大小,当大于了这个值就会将Thread由一个丢弃处理机制来处理
+ keepAliveTime? 默认都是0,当线程没有任务处理后,保持多长时间
+ TimeUnit? 时间单位,
+ ThreadFactory? 是构造Thread的方法,你可以自己去包装和传递,主要实现newThread方法即可
+ BlockingQueue 等待队列,当达到corePoolSize的时候,就向该等待队列放入线程信息(默认为一个LinkedBlockingQueue),运行中的队列属性为:workers,为一个HashSet;内部被包装了一层
+ RejectedExecutionHandler? 参数maximumPoolSize达到后丢弃处理的方法,java提供了4种丢弃处理的方法,当然你也可以自己弄,主要是要实现接口:RejectedExecutionHandler中的方法
3.2 提交任务
3.3 关闭线程池
3.4 工作机制
4.合理配置线程池
5.预定义的线程池
6.Executor框架
7.了解CompletionService
以上是关于并发编程—7.2线程池基础的主要内容,如果未能解决你的问题,请参考以下文章
Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析
Java并发编程21线程池ThreadPoolExecutor源码解析