自定義實現MyFixedThreadPool
自己想深入研究一下線程池的實現,所以自定義實現一下,首先考慮,既然線程池的初始化需要一個任務隊列與線程集合,具體的代碼如下:
package com.bdcloud.threadpool;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
/***
* 自定義線程池 newFixedThreadPool
*/
public class MyFixedThreadPool {
//存放任務
LinkedBlockingQueue<Runnable> queue;
//存放的工作線程
List<Worker> workers;
public MyFixedThreadPool(int queueSize,int workSize){
if (queueSize<=0 || workSize<=0){
throw new IllegalArgumentException("參數傳遞錯誤");
}
//初始化工作集合於工作隊列
this.queue = new LinkedBlockingQueue<>(queueSize);
this.workers = Collections.synchronizedList(new ArrayList<>(workSize));
//初始化所有的工作線程
for (int i = 0; i < workSize; i++) {
Worker worker = new Worker(this);
worker.start();
this.workers.add(worker);
}
}
//定義工作類
public static class Worker extends Thread{
private MyFixedThreadPool threadPool;
public Worker(MyFixedThreadPool threadPool){
this.threadPool = threadPool;
}
@Override
public void run() {
while (this.threadPool.isWorking||this.threadPool.queue.size()>0){
Runnable take = null;
try {
//從工作隊列取任務並執行
if (this.threadPool.isWorking){
take = threadPool.queue.take();
}else {
take = threadPool.queue.poll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (take!=null){
take.run();
System.out.println("當前的線程"+Thread.currentThread().getName()+"執行完畢");
}
}
}
}
/**
* 提交任務
* @param runnable
* @return
*/
public boolean submit(Runnable runnable){
if (this.isWorking){
return this.queue.offer(runnable);
}
return false;
}
//判斷線程池是否在運行
private volatile boolean isWorking = true;
/**
* 關閉線程池
* 1.就是線程池停止接收任務
* 2.若任務隊列中還有數據,則繼續取出並執行
* 3.中斷變量設置後,取任務的時候就不必要阻塞的取
* 4.一旦任務阻塞,我們就應該去中斷它
*/
private void shutDown(){
this.isWorking = false;
for (Thread thread:workers) {
if (thread.getState().equals(Thread.State.BLOCKED))
thread.interrupt();
}
}
public static void main(String[] args) throws InterruptedException {
MyFixedThreadPool pool = new MyFixedThreadPool(6,3);
//向線程池提交6個任務
for (int i = 0; i < 6; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println("提交了一個線程");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
//關閉線程池
pool.shutDown();
}
}