手寫一個簡單的線程池

線程池的接口定義

public interface ThreadPool<Job extends Runnable> {
    //執行一個job
    void execute(Job job);
    //關閉線程池
    void shutdown();
    //增加工作者線程
    void addWorker(int num);
    //減少工作者線程
    void removeWorker(int num);
    //得到正在執行的任務數量
    int getJobSize();
}

客戶端通過execute方法將任務提交到線程池執行,而客戶端自身不用等待任務執行完成。除了execute方法,線程池接口提供了增加/減少工作者線程以及關閉線程池的方法,這裏工作者線程代表一個重複執行任務的線程,而每個由客戶端提交的任務都將進入到一個工作隊列中等待工作者線程的處理。

線程池接口的默認實現

public class Job implements Runnable {
    @Override
    public void run() {

    }
}

從線程池的實現可以看到,客戶端調用execute方法時會不斷向任務列表jobs添加Job,而每個工作者線程會被不斷從jobs取出一個Job進行執行,當jobs爲空時,工作者線程進入等待狀態。
線程池的本質就是使用了一個線程安全的工作隊列連接工作者線程和客戶端線程,客戶端線程將任務放入工作隊列後返回,而工作者線程不斷從工作隊列取出工作並執行。當工作隊列爲空時,所有工作者線程均等待在工作隊列上,當有客戶端提交了一個任務之後會通知任意一個工作者線程,隨着大量的任務被提交,更多工作者線程會被喚醒。

public class DefaultThreadPool implements ThreadPool {
    //線程池最大限制數
    private static final int MAX_WORKER_NUMBERS=10;
    //線程池默認數量
    private static final int DEFAULT_WORKER_NUMBERS=5;
    //線程池最小數量
    private static final int MIN_WORKER_NUMBERS=1;
    //任務隊列,會向裏面插入任務
    private final LinkedList<Job> jobs=new LinkedList<>();
    //工作隊列
    private final List<Worker> workers= Collections.synchronizedList(new ArrayList<>());
    //工作線程數量
    private int workerNum=DEFAULT_WORKER_NUMBERS;
    //線程編號生成
    private AtomicLong threadNum=new AtomicLong();

    public DefaultThreadPool(){
        initWorkers(DEFAULT_WORKER_NUMBERS);
    }

    public DefaultThreadPool(int num) {
        //如果大於最大數量設置爲最大值,否則設置爲最小數量和設置數量的最大值
        workerNum=num>MAX_WORKER_NUMBERS?MAX_WORKER_NUMBERS: Math.max(num, MIN_WORKER_NUMBERS);
        initWorkers(workerNum);
    }

    //初始化線程工作者
    public void initWorkers(int num){
        for(int i=0;i<num;i++){
            Worker worker=new Worker();
            workers.add(worker);
            Thread thread=new Thread(worker,"Thread-"+threadNum.incrementAndGet());
            thread.start();
        }
    }

    //工作者,負責執行任務
    class Worker implements Runnable{
        //是否工作
        private volatile boolean running=false;

        @Override
        public void run() {
            while (running){
                Job job;
                synchronized (jobs){
                    //如果工作列表爲空就等待
                    while (jobs.isEmpty()){
                        try {
                            jobs.wait();
                        }catch (Exception e){
                            //感知外部的中斷操作
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                    //取出一個任務
                    job = jobs.removeFirst();
                }
                if(job!=null){
                    try{
                        job.run();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }

        public void shutdown(){
            running=false;
        }
    }




    @Override
    public void execute(Object job) {
        if(job!=null){
            //添加一個任務,然後通知
            synchronized (jobs){
                jobs.addLast((Job) job);
                jobs.notify();
            }
        }
    }

    @Override
    public void shutdown() {
        for(Worker worker:workers){
            worker.shutdown();
        }
    }

    @Override
    public void addWorker(int num) {
        synchronized (jobs){
            //限制新增的Worker數量不超過最大值
            if(num+this.workerNum>MAX_WORKER_NUMBERS)
                num=MAX_WORKER_NUMBERS-this.workerNum;
            initWorkers(num);
            this.workerNum+=num;
        }
    }

    @Override
    public void removeWorker(int num) {
        synchronized (jobs){
            if(num>=this.workerNum)
                throw new IllegalArgumentException("超過工作數量");
            //按照給定數量停止Worker
            int count=0;
            while (count<num){
                Worker worker=workers.get(count);
                if(workers.remove(worker)){
                    worker.shutdown();
                    count++;
                }
            }
            this.workerNum-=count;
        }
    }

    @Override
    public int getJobSize() {
        return jobs.size();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章