Java線程池簡單實現

 工作中經常用到線程池實現併發設計,基本都是使用的Java自帶的線程池,寫了個簡單的demo,說明Java自帶線程池的基本原理。

ThreadPool主要有coreSize(核心線程數)、maximumSize(最大線程數)、任務隊列和線程隊列參數,這主要是因爲線程池具有動態創建線程和銷燬的特性。爲此線程池的相關參數設置:

	private final int coreSize;   //核心線程數
    private final int maximumSize;  //最大工作線程數
    private final long keepAliveTime=5000;   //線程的存活時間(該值從線程獲取不到工作線程開始計時)
    private final  BiConsumer<Runnable,ThreadPool>rejectHandler;  //提交失敗的任務的處理方法
    private final BlockingQueue<Runnable> requestQueue;  // 任務請求隊列
    private final Set<Processor> processors;  //工作線程隊列

線程的創建與銷燬是根據提交的任務數量動態變化的,最重要的兩個閾值就是coreSize和maximumSize。下面對線程池的不同工作階段進行分析:

當任務數少於coreSize時
每個任務的提交,線程池都會創建一個相應的線程進行執行

當線程數等於coreSize,但是任務隊列未滿時
任務提交至任務隊列

當線程數等於coreSize,並且任務隊列已滿時
創建非核心線程處理任務

當線程數等於maximumSize
線程池不再創建工作線程,提交的任務都提交至任務隊列,如果任務隊列已滿,那麼提交的任務都會被拋棄

任務提交部分邏輯如下:

public void execute(Runnable command){
        if(processors.size()<coreSize){
            createProcessor(command,true);
            return;
        }
        if(!requestQueue.offer(command)){
            if(!createProcessor(command,false)){
                rejectHandler.accept(command,this);
            }
        }
    }

創建線程的邏輯

 private boolean createProcessor(Runnable command,boolean isCore){
        int threadThreshold=isCore?coreSize:maximumSize;
        if(processors.size()>=threadThreshold)
            return false;

        Processor processor=new Processor(command);
        processor.start();
        processors.add(processor);
        return true;
    }

每個線程的工作代碼

private void processorRun(Processor processor){
        boolean timeOut=false;
        Runnable runnable=processor.initRunnable;
        processor.initRunnable=null;
        while (true){
            try {
                if(timeOut)
                    break;
                if(runnable==null)
                    runnable=requestQueue.poll(keepAliveTime,TimeUnit.MILLISECONDS);

                if(runnable!=null)
                    runnable.run();
                else
                    timeOut=true;
            }catch (InterruptedException e){
                e.printStackTrace();
                timeOut=true;
            }
        }
        destroyProcessor(processor);
    }

完整的線程池代碼請至我的github查看:
代碼github地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章