线程池的实现

通常情况下。server软件会同一时候接纳并服务多个用户。当客户请求到达时,server主线程会创建一个工作者线程代表server为这个客户服务。当用户不须要服务的时候,线程结束,并释放创建线程用到的全部资源。

当下一个请求到达的时候,server又会创建一个新的线程为之服务。
可是因为创建线程须要非常多资源。包含处理器、内存等,这个过程在重复的创建线程中浪费了大量的处理器时间。尤其在大量并发客户的情况下,server对应会特别缓慢。这个时候就能够考虑用线程池。


线程池中先预留有一定数量的的线程。当有须要的时候,server就会从线程池中取出一个工作者线程,将任务赋给线程。当工作者线程运行完任务之后。它将会被又一次放回线程池中。注意,任务一般是指一个实现接口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;
                }
            }
        }
    }
}


posted @ 2017-07-03 08:07  lytwajue  阅读(114)  评论(0编辑  收藏  举报