线程池的简单实现

线程池介绍

(1)在没有采取线程池技术的时候,往往是一个任务一个线程的方式,这样将会创建数以万计的线程,使得操作系统频繁的进行线程上下文切换,增加系统的负载(线程的创建和消亡都是需要消耗系统资源的)
(2)线程池技术为了解决这个问题而产生,预先创造了若干数量的线程(Worker 线程),并且将线程的创建控制交给ThreadPool类,而不是客户端(客户端将任务job放入工作队列jobs后便返回)

线程池的实现

DefaultThreadPool主要负责workers 的封装与管理,并且提供addWorkers()、removeWorker()、shutdown()方法;及其增加job进工作队列的方法,execute(Job job)。
角色:
(1)jobs :工作队列(LinkedList),每一个job线程的run()负责执行任务;
(2)workers :工作者列表(ArrayList),每一个worker线程的run()负责不断地从工作队列上取出工作,然后执行;当工作队列中没有job任务时候,则等待阻塞,需要notify()或者notifyAll()唤醒

// 1. 抽象接口
public interface ThreadPool<Job extends Runnable> {
    //执行一个Job,这个Job需要实现Runnable
    void execute(Job job);
    //关闭线程池
    void shutdown();
    //增加工作者线程
    void addWorkers(int num);
    //减少工作者线程
    void removeWorker(int num);
    //得到正在等待执行的任务数量
    int getJobSize();
}
// 2. 默认实现
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

public class DefaultThreadPool<Job extends Runnable> implements ThreadPool<Job> {
    // 线程池最大限制数
    private static final int MAX_WORKEY_NUMBERS = 10;
    // 线程池默认的数量
    private static final int DEFAULT_WORKER_NUMBERS = 5;
    // 线程池最小的数量
    private static final int MIN_WORKEY_NUMBERS = 1;
    // 这是一个工作列表,将会向里边插入工作
    private final LinkedList<Job> jobs = new LinkedList<>();
    // 工作者列表(ArrayList是非线程安全的)
    private final List<Worker> workers = Collections.synchronizedList(new ArrayList<Worker>());
    // 工作者线程的数量
    private int workerNum = DEFAULT_WORKER_NUMBERS;
    // 线程编号生成(加了synchronized的long)
    private AtomicLong threadNum = new AtomicLong();

    public DefaultThreadPool() {
        initializeWorkers(DEFAULT_WORKER_NUMBERS);
    }

    public DefaultThreadPool(int num) {
        workerNum = num > MAX_WORKEY_NUMBERS ? MAX_WORKEY_NUMBERS : num < MIN_WORKEY_NUMBERS ? MIN_WORKEY_NUMBERS : num;
        initializeWorkers(workerNum);
    }

    private void initializeWorkers(int num) {
        for(int i=0;i<num;i++) {
            Worker worker = new Worker();
            workers.add(worker);
            Thread thread = new Thread(worker,"ThreadPool-Worker-"+threadNum.incrementAndGet());
            thread.start();
        }
    }

    // 增加一个job到队列尾部,然后唤醒一个工作者(确保有一个线程被唤醒即可,比notifyAll()开销小)
    @Override
    public void execute(Job job) {
        if(job!=null) {
            // 添加一个工作,然后进行通知
            synchronized(jobs) {
                jobs.add(job);
                jobs.notify();
            }
        }
    }

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

    @Override
    public void addWorkers(int num) {
        synchronized(jobs) {
            // 限制新增的Worker数量不能超过最大值
            if(num + this.workerNum > MAX_WORKEY_NUMBERS) {
                num = MAX_WORKEY_NUMBERS - this.workerNum;
            }
            initializeWorkers(num);
            this.workerNum += num;
        }
    }

    @Override
    public void removeWorker(int num) {
        synchronized(jobs) {
            if(num >= this.workerNum) {
                throw new IllegalArgumentException("beyond workNum");
            }
            // 按照给定的数量停止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();
    }

    /****
     *  工作者线程不断地从工作队列上取出工作,并且执行;
     *  当工作队列中没有job任务时候,则等待阻塞,需要notify()或者notifyAll()唤醒
     */
    class Worker implements Runnable {
        // 是否工作
        private volatile boolean running = true;
        // 每个工作者线程负责从jobs队列中取出一个job执行任务
        @Override
        public void run() {
            while(running) {
                Job job = null;
                synchronized (jobs) {
                    // 如果工作列表是空的,那么就wait
                    while(jobs.isEmpty()) {
                        try{
                            jobs.wait(); // 需要notify()或者notifyAll()唤醒
                        }catch(InterruptedException ex) {
                            // 感知到外部对WorkThread的中断操作,返回
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                    // 取出一个Job
                    job = jobs.removeFirst();
                }
                if(jobs!=null) {
                    try{
                        job.run();
                    }catch(Exception ex) {

                    }
                }
            }
        }

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

}



参考

《Java并发编程的艺术》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值