我们都知道线程池高效,是因为其节省了线程创建的资源。
那么到底是怎样节省的呢?其实也很简单,就是根据给的知道线程池大小去new 多少个 Thread ,然后在 run 方法里面无限循环,从线程池的 任务队列里面获取方法执行。
代码实例:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* 自定义固定大小的线程池
*/
public class FixedSizeThreadPool {
/**
* 装所有任务
*/
private ArrayBlockingQueue<Runnable> queue;
/**
* 装所有线程
*/
private List<Thread> workes;
// 线程名
private String tname;
public FixedSizeThreadPool(int poolSize , int taskSize , String tname){
if(poolSize<0 || taskSize<0){
throw new IllegalArgumentException("非法的参数");
}
// 实例化无界队列,用于装任务
this.queue = new ArrayBlockingQueue<>(taskSize);
this.workes = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < poolSize; i++) {
Worker worker = new Worker(this);
worker.setThreadName(tname + "===>" + i);
worker.start();
this.workes.add(worker);
}
}
/**
* 开几个线程执行,最大执行多少个任务
* @param poolSize
* @param taskSize
*/
public FixedSizeThreadPool(int poolSize , int taskSize){
this(poolSize , taskSize , "Thread");
}
/**
* 提交任务
* @param task
* @return
*/
public boolean submit(Runnable task){
return this.queue.offer(task);
}
/**
* 关闭线程池
*/
public void shutdown(){
// 当任务队列里面的数据为空的时候,则证明任务都执行完毕了(或者已经开始执行了),就可以进行下一步关闭线程了
while (this.queue.size()!=0){
}
for (int i = 0; i < this.workes.size(); i++) {
((Worker) this.workes.get(i)).setFlag(false);
}
}
public static class Worker extends Thread{
private boolean flag;
public void setFlag(boolean flag) {
this.flag = flag;
}
// 固定线程池对象,从里面拿出 任务来执行
private FixedSizeThreadPool pool;
public Worker(FixedSizeThreadPool pool){
this.flag = true;
this.pool = pool;
}
public void setThreadName(String tname){
super.setName(tname);
}
// 不断循环,从队列中拿到任务来执行
@Override
public void run() {
while (flag){
Runnable task = null;
try {
task = this.pool.queue.poll(10,TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (task != null) {
task.run();
System.out.println("线程" + Thread.currentThread().getName() + "执行了..." );
}
}
System.out.println("线程死亡!!!");
}
}
public static void main(String[] args) {
FixedSizeThreadPool pool = new FixedSizeThreadPool(3, 6);
for (int i = 0; i < 6; i++) {
final int index = i;
pool.submit(new Runnable() {
@Override
public void run() {
System.err.println("start exec task " + index);
}
});
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 10; i < 16; i++) {
final int index = i;
pool.submit(new Runnable() {
@Override
public void run() {
System.err.println("start exec task " + index);
}
});
}
pool.shutdown();
}
}