zoukankan      html  css  js  c++  java
  • 线程池的实现

    通常情况下。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("
    Task Queue Size:" + taskQueue.size());
            for (int i = 0; i < workers.length; i++) {
                sb.append("
    Worker " + 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;
                    }
                }
            }
        }
    }


  • 相关阅读:
    【原创】交换机多端口抓包配置教程
    【转】常用的C语言宏定义
    【转】C语言中可变参数的函数(三个点,“...”)
    【转】SIP响应状态码
    【转】交换机常用功能——端口监控应用举例
    【转】网线水晶头的接法
    【转】三层交换机vlan接口配置
    【转】各种常见的交换机接口及连接方法介绍
    【转】Internet多媒体会议工具包的使用示例
    【转】SDP
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7109380.html
Copyright © 2011-2022 走看看