在这里使用Java实现一个简单的线程池,虽然实现简单,但可以帮助我们理解线程的的原理。
1.创建线程类
创建一个线程池类,其核心就是工作线程列表和阻塞任务队列,在这里新建线程池对象的时候就会初始化阻塞任务队列和创建对相应核心线程数并运行,每个线程都运行着一个循环结构,循环体内部获取阻塞队列中的任务并执行,这里正是利用用阻塞队列的特性,如果队列中不存在任务线程将会阻塞在这里等待任务加入。
不好意思啊,都是废话,请看代码:?
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* 实现Java线程池
*/
public class MyThreadPool {
/** 默认线程数量 */
private final static int THREAD_COUNT = 5;
/** 默认任务队列的容量 */
private final static int DEFAULT_CAPACITY = 100;
/** 阻塞队列 */
private final BlockingQueue<Runnable> workQueue;
/** 线程列表 */
private ArrayList<Thread> threads;
/** 核心线程池 */
private int corePoolSize;
/** 队列容量 */
private int capacity;
public MyThreadPool(int corePoolSize,int capacity){
this.corePoolSize = corePoolSize;
if(corePoolSize <= 0){
this.corePoolSize = THREAD_COUNT;
}
this.capacity = capacity;
if(capacity<=0){
this.capacity = DEFAULT_CAPACITY;
}
/** 初始化任务队列 */
workQueue = new ArrayBlockingQueue<>(this.capacity);
/** 初始化工作线程 */
threads = new ArrayList<>(this.corePoolSize);
for (int i = 0; i < this.corePoolSize; i++) {
WorkThread workThread = new WorkThread();
threads.add(workThread);
workThread.start();
}
}
/**
* 加入任务
* @param task 任务
*/
public void execute(Runnable task) {
try {
this.workQueue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 工作线程
*/
class WorkThread extends Thread{
Runnable task = null;
@Override
public void run() {
try {
while(!isInterrupted()){
/** 阻塞队列在这里阻塞等待任务的加入 */
task = workQueue.take();
task.run();
task = null;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 销毁线程池
*/
public void destroy(){
/** 遍历终止所有工作线程 */
Iterator it = this.threads.iterator();
while(it.hasNext()){
Thread t = (Thread) it.next();
t.interrupt();
it.remove();
}
/** 清空任务队列 */
workQueue.clear();
}
@Override
public String toString() {
return "WorkThread number:"+this.corePoolSize+" wait task number:"+workQueue.size();
}
}
2. 测试线程池
2.1 创建一个任务类,实现Runnable接口。
public class Task implements Runnable{
String taskName;
public Task(){};
public Task(String taskName){
this.taskName = taskName;
}
@Override
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String name = Thread.currentThread().getName();
System.out.println(name+" start-->"+taskName+" "+sdf.format(new Date()));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// Thread.currentThread().interrupt();
e.printStackTrace();
}
System.out.println(name+" end-->"+taskName+" "+sdf.format(new Date()));
}
}
2.2 创建一个主类运行程序
public class Main {
public static void main(String[] args) {
/** 创建一个有5个核心线程和100个线程池等待队列的线程池对象*/
MyThreadPool myThreadPool = new MyThreadPool(5,100);
/** 加入8个任务 */
for (int i = 0; i < 8; i++) {
myThreadPool.execute(new Task("TaskName"+(i+1)));
}
//...
System.out.println(myThreadPool.toString());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(myThreadPool.toString());
// myThreadPool.destroy();
}
}
2.3 运行结果:
Thread-0 start-->TaskName3 2019-05-16 22:36:27
Thread-2 start-->TaskName2 2019-05-16 22:36:27
Thread-4 start-->TaskName5 2019-05-16 22:36:27
Thread-1 start-->TaskName4 2019-05-16 22:36:27
Thread-3 start-->TaskName1 2019-05-16 22:36:27
Thread-3 end-->TaskName1 2019-05-16 22:36:29
Thread-4 end-->TaskName5 2019-05-16 22:36:29
Thread-1 end-->TaskName4 2019-05-16 22:36:29
Thread-4 start-->TaskName6 2019-05-16 22:36:29
Thread-1 start-->TaskName7 2019-05-16 22:36:29
Thread-3 start-->TaskName8 2019-05-16 22:36:29
Thread-2 end-->TaskName2 2019-05-16 22:36:29
Thread-0 end-->TaskName3 2019-05-16 22:36:29
WorkThread number:5 wait task number:0
Thread-3 end-->TaskName8 2019-05-16 22:36:31
Thread-4 end-->TaskName6 2019-05-16 22:36:31
Thread-1 end-->TaskName7 2019-05-16 22:36:31
完毕?
版权声明:本文为qq_29550537原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。