練習手寫線程池
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* ...
*
* @author : [email protected]
* Date : 2018/12/18 下午4:48
*/
public class TestPool {
private int coreSize,
maxSize;
private AtomicInteger running = new AtomicInteger(0);
private BlockingQueue<Runnable> queue;
public TestPool(int coreSize, int maxSize, BlockingQueue<Runnable> queue) {
this.coreSize = coreSize;
this.maxSize = maxSize;
this.queue = queue;
}
public void execute(Runnable runnable) {
if (running.get() < coreSize) {
if(!addWorker(runnable)){
reject();
}
} else {
System.out.println("當前隊列大小:"+queue.size());
//添加任務到隊列中
if(!queue.offer(runnable)){
//如果添加失敗則繼續創建線程
System.out.println("offer 失敗,當前線程數:"+running.get());
if(!addWorker(runnable)){
reject();
}
}
}
}
private void reject() {
throw new RuntimeException("超出大小,當前線程數:"+running.get()+" 隊列大小:"+queue.size());
}
private boolean addWorker(Runnable runnable) {
//如果當前線程數大於最大數則創建失敗
if (running.get() >= maxSize) {
return false;
}
Worker worker = new Worker(runnable);
worker.start();
return true;
}
private class Worker extends Thread {
private Runnable runnable;
public Worker(Runnable runnable) {
this.runnable = runnable;
//增加線程運行線程數
System.out.println("創建線程:當前線程數:"+running.incrementAndGet());
}
@Override
public void run() {
try {
while (true) {
//運行線程
runnable.run();
System.out.println("運行結束,當前線程數:"+running.get());
//如果當前運行線程數大於核心大小就退出線程
if (running.get() > coreSize) {
break;
}else{
//反之從隊列裏取數據,理論上至少存活coreSize個線程
try {
System.out.println("000000:隊列大小:"+queue.size());
runnable = queue.take();
System.out.println("11111111:隊列大小:"+queue.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
//線程結束,減少運行數
running.decrementAndGet();
System.out.println("結束線程,當前線程數:"+running.get());
}
}
}
public static void main(String[] args) {
Thread.currentThread().setName("main");
TestPool pool = new TestPool(2, 2, new ArrayBlockingQueue<>(3));
for(int i=0;i<100;i++){
final int j = i;
System.out.println("i="+i+" "+Thread.currentThread().getName());
pool.execute(()->{
try {
Thread.sleep(100);
System.out.println("睡0.1秒 完成:"+j);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}