簡單實現java線程池
阿新 • • 發佈:2018-05-18
隊列 imp trac poi resize ren .com lsi urn
使用多線程以及線程池的意義無需多說,要想掌握線程池,最好的方法還是自己手動去實現。
一、實現思路
(網絡盜圖)
總的來說,所有的任務在BlockingQueue中進行等待,由Worker進行具體的操作,Worker才是真正的工作線程。
二、代碼
1、線程池類
package com.ty.thread;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @author Taoyong
* @date 2018年5月17日
* 天下沒有難敲的代碼!
*/
public class ThreadPoolExecutor {
//維護線程的list
private Set<Thread> threadList = new HashSet<Thread>();
/*
* 阻塞隊列是線程安全的,主要使用在生產/消費者的場景
*/
private BlockingQueue<Task> blockingQueue;
//線程池的工作線程數
private int poolSize = 0;
//線程池的核心容量
private int coreSize = 0;
private boolean shutDown = false;
public ThreadPoolExecutor(int size) {
this.poolSize = size;
blockingQueue = new LinkedBlockingQueue<>(poolSize);
}
public void execute(Task task) throws InterruptedException {
if(shutDown == true) {
return;
}
if(coreSize < poolSize) {
blockingQueue.offer(task);
produceWorker(task);
}else {
blockingQueue.put(task);
}
}
private void produceWorker(Task task) throws InterruptedException {
if(task == null) {
throw new NullPointerException("非法參數:傳入的task對象為空!");
}
if(shutDown == true) {
return;
}
Thread thread = new Thread(new Worker());
threadList.add(thread);
coreSize++;
thread.start();
}
public void shutDown() {
if(threadList == null || threadList.size() == 0) {
return;
}
shutDown = true;
for(Thread thread: threadList) {
System.out.println(thread.getName() + " interrupt");
thread.interrupt();
}
}
/*
* 此內部類是實際上的工作線 worker是實現了Runnable接口的實際工作線程,通過while(true)循環從BlockingQueue中取任務執行。
*
*/
class Worker implements Runnable {
@Override
public void run() {
while(true && shutDown == false) {
try {
blockingQueue.take().doJob();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2、Task類(需要被線程處理的任務類)
package com.ty.thread;
/**
* @author Taoyong
* @date 2018年5月17日
* 天下沒有難敲的代碼!
*/
public class Task {
//通過taskId對任務進行標識
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
public void doJob() {
System.out.println("線程" + Thread.currentThread().getName() + "正在處理任務!");
}
public int getId() {
return taskId;
}
}
3、測試類
package com.ty.thread;
/**
* @author Taoyong
* @date 2018年5月17日
* 天下沒有難敲的代碼!
*/
public class ThreadPoolExecutorTest {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3);
for(int i = 0; i < 10; i++) {
Task task = new Task(i);
threadPoolExecutor.execute(task);
}
threadPoolExecutor.shutDown();
}
}
4、運行結果
線程Thread-0正在處理任務!
線程Thread-2正在處理任務!
線程Thread-0正在處理任務!
線程Thread-1正在處理任務!
線程Thread-2正在處理任務!
線程Thread-2正在處理任務!
線程Thread-1正在處理任務!
線程Thread-2正在處理任務!
線程Thread-0正在處理任務!
Thread-1 interrupt
Thread-0 interrupt
Thread-2 interrupt
當第十個任務待處理時,整個線程池已經被shutDown,整個流程結束。
簡單實現java線程池