线程池是重点也是难点, 结合知识点较多, 一番理解后写出简单的线程池实现
package edu.cxf.dongnao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 綫程池.
*/
public class KeithTreadPool {
// 1.任務倉庫
private BlockingQueue<Runnable> blockingQueue;
// 2.服務人員集合
private List<Thread> workers;
// 關閉標識
private volatile boolean isWorking = true;
// 3.服務人員
class Worker extends Thread {
private KeithTreadPool keithTreadPool;
public Worker(KeithTreadPool keithTreadPool) {
this.keithTreadPool = keithTreadPool;
}
@Override
public void run() {
while (this.keithTreadPool.isWorking || this.keithTreadPool.blockingQueue.size() > 0) {
Runnable task = null;
try {
if (this.keithTreadPool.isWorking) {
task = this.keithTreadPool.blockingQueue.take();
} else {
task = this.keithTreadPool.blockingQueue.poll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (task != null) {
task.run();
System.out.println(Thread.currentThread().getName() + "完成執行任務!");
}
}
}
}
// 4.初始化倉庫和服務組織大小
public KeithTreadPool(int poolSize, int taskSize) {
if (poolSize <= 0 || taskSize <= 0) {
throw new IllegalArgumentException("參數錯誤");
}
this.blockingQueue = new LinkedBlockingQueue<>(taskSize);
this.workers = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < poolSize; i++) {
Worker worker = new Worker(this);
worker.start();
workers.add(worker);
}
}
// 5.前臺接待引導客人排隊
public boolean submit(Runnable runnable) {
if (this.isWorking) {
return this.blockingQueue.offer(runnable);
} else {
return false;
}
}
// 6.關閉
// a.關閉時候--前臺--不再接待客人
// b.關閉時候--排隊--執行完
// c.關閉時候--服務人員--再去拿客人時就不能阻塞
// d.關閉時候--服務人員已經阻塞--中斷他
//
public void shutdown() {
// 設置關閉標識
this.isWorking = false;
for (Thread worker : workers) {
if (worker.getState().equals(Thread.State.BLOCKED) || worker.getState().equals(Thread.State.WAITING)) {
worker.interrupt();
}
}
}
public static void main(String[] args) {
KeithTreadPool keithTreadPool = new KeithTreadPool(4, 20);
for (int i = 0; i < 20; i++) {
final int current = i;
keithTreadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("計算第" + current + "次過程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
keithTreadPool.shutdown();
}
}
附 : 一组图片帮助理解
版权声明:本文为madeByOurselves原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。