package threadpool_test; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; /** * 自定义一个简单的线程池 * * ***/ public class ThreadPool { private static final int coreThreadNum=3;//核心线程数 private static final int maxThreadNum=8;//最大线程数 private boolean working=true;//打开、关闭线程池 private BlockingQueue<Thread> workThreads=new LinkedBlockingDeque<>(maxThreadNum);//当前工作线程 private BlockingQueue<Runnable> tasks=new LinkedBlockingDeque<>(10);//任务队列 public void execute(Runnable task) throws InterruptedException{ if(task==null) throw new NullPointerException(); int workNum=workThreads.size(); if(workNum<coreThreadNum ){//当前工作线程少于核心线程数,立即启动一个线程进行工作 Worker worker=new Worker(task); Thread thread=new Thread(worker); workThreads.offer(thread);//特殊值,add会抛出异常 thread.start(); } else if(tasks.size()<10){//任务池还没满,就把任务放进任务池里 tasks.offer(task); } else if(workNum<maxThreadNum && tasks.size()==10){//任务队列满,开启多余线程来完成任务 Worker worker=new Worker(); Thread thread=new Thread(worker); System.out.println("开启新线程了"+thread.getName()); workThreads.offer(thread); thread.start(); } else{ System.out.println("放弃该任务"); return; } } public void shutDown(){ this.working=false; for(Thread worker:workThreads){ System.out.println("终止线程名:"+worker.getName()); worker.interrupt(); } System.out.println("终止线程池线程"); Thread.currentThread().interrupt(); } private class Worker implements Runnable{//任务包装类 private Runnable task_origal; public Worker() { } public Worker(Runnable task) { this.task_origal=task; } @Override public void run() { if(task_origal!=null) task_origal.run(); while(working){ try { Runnable task=tasks.take();//阻塞提取任务,阻塞状态下的中断并不会真的中断 task.run(); } catch (InterruptedException e) { System.out.println("真的终止了"); Thread.currentThread().interrupt(); } } } } }
package threadpool_test; import java.util.concurrent.TimeUnit; /** * 测试类 * **/ public class testMain { public static void main(String[] args) throws InterruptedException { ThreadPool pool=new ThreadPool(); for(int i=0;i<20;i++){ pool.execute(new Task("任务"+i)); } TimeUnit.SECONDS.sleep(4); pool.shutDown(); } }
显示结果:
当前运行线程名:Thread-0当前任务名为:任务0 当前运行线程名:Thread-2当前任务名为:任务2 当前运行线程名:Thread-2当前任务名为:任务4 当前运行线程名:Thread-2当前任务名为:任务5 当前运行线程名:Thread-2当前任务名为:任务6 当前运行线程名:Thread-2当前任务名为:任务7 当前运行线程名:Thread-2当前任务名为:任务8 当前运行线程名:Thread-2当前任务名为:任务9 当前运行线程名:Thread-2当前任务名为:任务10 当前运行线程名:Thread-2当前任务名为:任务11 当前运行线程名:Thread-2当前任务名为:任务12 开启新线程了Thread-3 当前运行线程名:Thread-1当前任务名为:任务1 当前运行线程名:Thread-1当前任务名为:任务14 当前运行线程名:Thread-3当前任务名为:任务15 当前运行线程名:Thread-3当前任务名为:任务16 当前运行线程名:Thread-3当前任务名为:任务17 当前运行线程名:Thread-3当前任务名为:任务18 当前运行线程名:Thread-3当前任务名为:任务19 当前运行线程名:Thread-0当前任务名为:任务3 终止线程名:Thread-0 真的终止了 终止线程名:Thread-1 终止线程名:Thread-2 真的终止了 真的终止了 终止线程名:Thread-3 终止线程池线程 真的终止了
ps:该线程池功能非常之简单,仅为了加深线程池核心原理而做。里面关于任务队列满后的处理情况,在这里直接简单的使用放弃该任务的方法;