手写实现一个FixedSizeThreadPool

       实现一个固定数量线程池,主要用到消息队列实现任务仓库以及特定数量的工作线程。完整代码贴在后面,给出了测试方法,值得注意点在于对线程池进行中断的时候的一系列连锁反应,以及使用Collections.synchronizedList同步普通数组使之变为线程安全的技巧。详见代码注释。

//实现固定数量线程池 主要用到消息队列实现任务仓库 以及特定数量的工作线程
//最值得注意的是 中断的时候 以及使用Collections.synchronizedList 方法同步普通数组的时候
public class FixedSizeThreadPool {
    //增加一个变量判断线程池的状态 是不是正在工作
    private volatile boolean isWorking =true;
    //需要仓库 使用阻塞队列
    private BlockingQueue<Runnable> blockQueue;
    //线程的集合
    private List<Thread> wokers;
    //工作线程
    static  class Worker extends  Thread{
        private  FixedSizeThreadPool pool;
        public  Worker(FixedSizeThreadPool pool){ 
            this.pool =pool;
        }
        @Override
        public void run(){
            while (this.pool.isWorking||this.pool.blockQueue.size()>0){
                Runnable task =null;
                try {
                    if(this.pool.isWorking)
                    task=this.pool.blockQueue.take();
                    else
                        task = this.pool.blockQueue.poll();
                    if(task!=null){
                        //非常值得注意的是,Runnable接口中是不存在start方法的,唯一的就是run方法 调用run方法相当于使用普通方法
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
    //把任务提交到任务仓库的方法
    public  boolean submit(Runnable task){
        if(isWorking)
        return this.blockQueue.offer(task);
        else
            return false;
    }
    //线程池的初始化
    public FixedSizeThreadPool(int poolSize,int taskSize){
        if(poolSize<=0 || taskSize<=0) throw new IllegalArgumentException("非法参数");
        this.blockQueue = new LinkedBlockingDeque<>(taskSize);
        this.wokers = Collections.synchronizedList( new ArrayList<>());
        for(int i =0;  i < poolSize ;  i++){
            Worker worker = new Worker(this);
            worker.start();
            wokers.add(worker);
        }
        
    }
    //关闭线程池的方法
    //需要注意的是四个方面
    //1.仓库停止接受任务
    //2.仓库中的剩余的任务继续的执行
    //3.拿任务的时候 不要阻塞了
    //4.一旦任务阻塞了,中断线程
    public  void shutdown(){
        this.isWorking =false;
        for(Thread thread: wokers){
            if(thread.getState().equals(Thread.State.BLOCKED)){
                //中断掉
                thread.interrupt();
            }

        }
    }
    public static void main(String[] args){
        FixedSizeThreadPool fixedSizeThreadPool = new FixedSizeThreadPool(3, 6);
        for(int i =0;  i < 6 ;  i++){
            fixedSizeThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("放入一个新的线程");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        System.out.println("线程池满了");

                    }
                }
            });
        }
        fixedSizeThreadPool.shutdown();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值