码迷,mamicode.com
首页 > 编程语言 > 详细

线程池的实现

时间:2015-07-28 13:01:31      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:线程池   线程   并发   服务器   

通常情况下,服务器软件会同时接纳并服务多个用户。当客户请求到达时,服务器主线程会创建一个工作者线程代表服务器为这个客户服务。当用户不需要服务的时候,线程结束,并释放创建线程用到的所有资源。当下一个请求到达的时候,服务器又会创建一个新的线程为之服务。
但是由于创建线程需要很多资源,包括处理器、内存等,这个过程在反复的创建线程中浪费了大量的处理器时间。尤其在大量并发客户的情况下,服务器相应会特别缓慢。这个时候就可以考虑用线程池。
线程池中先预留有一定数量的的线程,当有需要的时候,服务器就会从线程池中取出一个工作者线程,将任务赋给线程。当工作者线程执行完任务之后,它将会被重新放回线程池中。注意,任务通常是指一个实现接口runnable的类的实例。

接下来,是一个简单线程池的实现:

public final class ThreadPool {

    private static ThreadPool instance = ThreadPool.getInstance();

    public static final int SYSTEM_BUSY_TASK_COUNT = 150;   //系统繁忙的任务数
    /* 默认池中线程数 */
    public static int worker_num = 5;
    /* 已经处理的任务数 */
    private static int taskCounter = 0;

    public static boolean systemIsBusy = false;

    private static List<Task> taskQueue = Collections
            .synchronizedList(new LinkedList<Task>());
    /* 池中的所有线程 */
    public PoolWorker[] workers;

    private ThreadPool() {
        workers = new PoolWorker[5];
        for (int i = 0; i < workers.length; i++) {
            workers[i] = new PoolWorker(i);
        }
    }
    /*构造函数*/
    private ThreadPool(int pool_worker_num) {
        worker_num = pool_worker_num;
        workers = new PoolWorker[worker_num];
        for (int i = 0; i < workers.length; i++) {
            workers[i] = new PoolWorker(i);
        }
    }
    /*通过该函数得到线程池的实例*/
    public static synchronized ThreadPool getInstance() {
        if (instance == null)
            return new ThreadPool();
        return instance;
    }
    /**
    * 增加新的任务
    * 每增加一个新任务,都要唤醒任务队列
    * @param newTask
    */
    public void addTask(Task newTask) {
        synchronized (taskQueue) {
            newTask.setTaskId(++taskCounter);
            newTask.setSubmitTime(new Date());
            taskQueue.add(newTask);
            /* 唤醒队列, 开始执行 */
            taskQueue.notifyAll();
        }
    }
    /**
    * 批量增加新任务
    * @param taskes
    */
    public void batchAddTask(Task[] taskes) {
        if (taskes == null || taskes.length == 0) {
            return;
        }
        synchronized (taskQueue) {
            for (int i = 0; i < taskes.length; i++) {
                if (taskes[i] == null) {
                    continue;
                }
                taskes[i].setTaskId(++taskCounter);
                taskes[i].setSubmitTime(new Date());
                taskQueue.add(taskes[i]);
            }
            /* 唤醒队列, 开始执行 */
            taskQueue.notifyAll();
        }
        for (int i = 0; i < taskes.length; i++) {
            if (taskes[i] == null) {
                continue;
            }
        }
    }
    /**
    * 线程池信息
    * @return
    */
    public String getInfo() {
        StringBuffer sb = new StringBuffer();
        sb.append("\nTask Queue Size:" + taskQueue.size());
        for (int i = 0; i < workers.length; i++) {
            sb.append("\nWorker " + i + " is "
                    + ((workers[i].isWaiting()) ? "Waiting." : "Running."));
        }
        return sb.toString();
    }
    /**
    * 销毁线程池
    */
    public synchronized void destroy() {
        for (int i = 0; i < worker_num; i++) {
            workers[i].stopWorker();
            workers[i] = null;
        }
        taskQueue.clear();
    }

    /**
    * 池中工作线程(线程池拥有多个线程对象)
    */
    private class PoolWorker extends Thread {
        private int index = -1;
        /* 该工作线程是否有效 */
        private boolean isRunning = true;
        /* 该工作线程是否可以执行新任务 */
        private boolean isWaiting = true;

        /*构造函数*/
        public PoolWorker(int index) {
            this.index = index;
            start();
        }

        public void stopWorker() {
            this.isRunning = false;
        }

        public boolean isWaiting() {
            return this.isWaiting;
        }
        /**
        * 循环执行任务
        * 这也许是线程池的关键所在
        */
        public void run() {
            while (isRunning) {
                Task task = null;
                synchronized (taskQueue) {
                    while (taskQueue.isEmpty()) {
                        try {
                            /* 任务队列为空,则等待有新任务加入从而被唤醒 */
                            taskQueue.wait(20);
                        } catch (InterruptedException ie) {
                            ie.printStackTrace();
                        }
                    }
                    /* 取出任务执行 */
                    task = (Task) taskQueue.remove(0);
                }
                if (task != null) {
                    isWaiting = false;
                    try {
                        /* 该任务是否需要立即执行 */
                        if (task.needExecuteImmediate()) {
                            new Thread(task).start();   //开启新线程执行这个Task
                        } else {
                        	System.out.println("一个任务正在执行");
                            task.run();                 //执行这个Task的是同一个线程
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    isWaiting = true;
                    task = null;
                }
            }
        }
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

线程池的实现

标签:线程池   线程   并发   服务器   

原文地址:http://blog.csdn.net/liuruiqun/article/details/47103411

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!