线程池详解
来源:互联网 发布:it618淘宝客导购源码 编辑:程序博客网 时间:2024/06/06 12:40
在新接触一门技术之前,都应该从下面几个步骤入手:
首先是概念及作用,那么我们首先就要弄清楚什么是线程池;
其次是如何使用,通常情况下最好使用一个例子来说明;
最后是内部原理,因为这是考验你是否掌握一门技术的关键。
下面,我就从三个方面对线程池作详细的讲述。
一、线程池是什么?
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPoolManager):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等。可以简单的理解为我们创建的线程。
4、任务队列(taskQueue):用于存放没有处理的任务,提供一种缓冲机制。可以简单的理解为线程池中尚未被执行的线程队列。
作用:线程池作用就是限制系统中执行线程的数量。
二、线程池的使用实例
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadTest { public static void main(String[] args) { //创建一个可重用固定线程数的线程池 ExecutorService pool = Executors. newFixedThreadPool(2); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); //关闭线程池 pool.shutdown(); }}class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + "正在执行。。。"); }}
分析:
Executors:是线程池管理器;
ExecutorService pool:线程池;
Thread t1/t2/t3/t4/t5:任务;
任务队列封装在线程池ExecutorService 中。
三、线程池的实现原理
import java.util.Collections;import java.util.Date;import java.util.LinkedList;import java.util.List;import org.apache.log4j.Logger;/** * 线程池类 */public class ThreadPool { private static Logger logger = Logger.getLogger(ThreadPool.class); private static Logger taskLogger = Logger.getLogger("TaskLogger"); private static boolean debug = taskLogger.isDebugEnabled();// private static boolean debug = taskLogger.isInfoEnabled(); /* 单例 */ 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(); } logger.info("Submit Task<" + newTask.getTaskId() + ">: " + newTask.info()); } /** * 批量增加新任务 * @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; } logger.info("Submit Task<" + taskes[i].getTaskId() + ">: " + taskes[i].info()); } } /** * 线程池信息 * @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(); } /** * 池中工作线程 * * @author obullxl */ 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 r = null; synchronized (taskQueue) { while (taskQueue.isEmpty()) { try { /* 任务队列为空,则等待有新任务加入从而被唤醒 */ taskQueue.wait(20); } catch (InterruptedException ie) { logger.error(ie); } } /* 取出任务执行 */ r = (Task) taskQueue.remove(0); } if (r != null) { isWaiting = false; try { if (debug) { r.setBeginExceuteTime(new Date()); taskLogger.debug("Worker<" + index + "> start execute Task<" + r.getTaskId() + ">"); if (r.getBeginExceuteTime().getTime() - r.getSubmitTime().getTime() > 1000) taskLogger.debug("longer waiting time. " + r.info() + ",<" + index + ">,time:" + (r.getFinishTime().getTime() - r .getBeginExceuteTime().getTime())); } /* 该任务是否需要立即执行 */ if (r.needExecuteImmediate()) { new Thread(r).start(); } else { r.run(); } if (debug) { r.setFinishTime(new Date()); taskLogger.debug("Worker<" + index + "> finish task<" + r.getTaskId() + ">"); if (r.getFinishTime().getTime() - r.getBeginExceuteTime().getTime() > 1000) taskLogger.debug("longer execution time. " + r.info() + ",<" + index + ">,time:" + (r.getFinishTime().getTime() - r .getBeginExceuteTime().getTime())); } } catch (Exception e) { e.printStackTrace(); logger.error(e); } isWaiting = true; r = null; } } } }}
package com.test;import java.util.Date;/*** 所有任务接口* 其他任务必须继承访类** @author obullxl*/public abstract class Task implements Runnable { // private static Logger logger = Logger.getLogger(Task.class); /* 产生时间 */ private Date generateTime = null; /* 提交执行时间 */ private Date submitTime = null; /* 开始执行时间 */ private Date beginExceuteTime = null; /* 执行完成时间 */ private Date finishTime = null; private long taskId; public Task() { this.generateTime = new Date(); } /** * 任务执行入口 */ public void run() { /** * 相关执行代码 * * beginTransaction(); * * 执行过程中可能产生新的任务 subtask = taskCore(); * * commitTransaction(); * * 增加新产生的任务 ThreadPool.getInstance().batchAddTask(taskCore()); */ } /** * 所有任务的核心 所以特别的业务逻辑执行之处 * * @throws Exception */ public abstract Task[] taskCore() throws Exception; /** * 是否用到数据库 * * @return */ protected abstract boolean useDb(); /** * 是否需要立即执行 * * @return */ protected abstract boolean needExecuteImmediate(); /** * 任务信息 * * @return String */ public abstract String info(); public Date getGenerateTime() { return generateTime; } public Date getBeginExceuteTime() { return beginExceuteTime; } public void setBeginExceuteTime(Date beginExceuteTime) { this.beginExceuteTime = beginExceuteTime; } public Date getFinishTime() { return finishTime; } public void setFinishTime(Date finishTime) { this.finishTime = finishTime; } public Date getSubmitTime() { return submitTime; } public void setSubmitTime(Date submitTime) { this.submitTime = submitTime; } public long getTaskId() { return taskId; } public void setTaskId(long taskId) { this.taskId = taskId; }}
0 0
- c#线程池详解
- c#线程池详解
- c#线程池详解
- c#线程池详解
- c#线程池详解
- c#线程池详解
- C# 线程池详解
- java 线程池详解
- java线程池详解
- java 线程池 详解
- 线程池详解
- Java线程池详解
- JAVA线程池详解
- java线程池详解
- java线程池详解
- Android 线程池详解
- 线程池详解
- 线程池详解
- 欢迎使用CSDN-markdown编辑器
- [leetcode190]Reverse Bits
- hdu 1044 Collect More Jewels(BFS+DFS)
- Java List接口
- HDU 1078 FatMouse and Cheese
- 线程池详解
- 1 - 统计学习方法概论
- 数据库里写了很多存储过程,想用SQL语句查出哪些存储过程包含字段(如:user_id)
- android 最优绘制圆图方法
- 如何脱离tutorial使用igllib
- 形式系统(Formal System)-前言
- Android视频播放(一)
- [leetcode] House Robber
- 扫描AVCapture -- 完整版(指定区域+闪光灯)