线程池的作用:

线程池作用就是限制系统中执行线程的数量。

根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程
排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程
池中有等待的工作线程,就可以开始运行了;否则进入等待队列。

为什么要用线程池:

  1. 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
  2. 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)

线程池类

  1. package com.tdt.impl.ls;
  2. import java.util.LinkedList;
  3. /**
  4. * @project LocationGateway
  5. * @author sunnylocus
  6. * @verson 1.0.0
  7. * @date   Aug 2, 2008
  8. * @jdk    1.4.2
  9. */
  10. public class ThreadPool extends ThreadGroup {
  11. private boolean isClosed = false;  //线程池是否关闭
  12. private LinkedList workQueue;      //工作队列
  13. private static int threadPoolID = 1;  //线程池的id
  14. public ThreadPool(int poolSize) {  //poolSize 表示线程池中的工作线程的数量
  15. super(threadPoolID + "");      //指定ThreadGroup的名称
  16. setDaemon(true);               //继承到的方法,设置是否守护线程池
  17. workQueue = new LinkedList();  //创建工作队列
  18. for(int i = 0; i < poolSize; i++) {
  19. new WorkThread(i).start();   //创建并启动工作线程,线程池数量是多少就创建多少个工作线程
  20. }
  21. }
  22. /** 向工作队列中加入一个新任务,由工作线程去执行该任务*/
  23. public synchronized void execute(Runnable task) {
  24. if(isClosed) {
  25. throw new IllegalStateException();
  26. }
  27. if(task != null) {
  28. workQueue.add(task);//向队列中加入一个任务
  29. notify();           //唤醒一个正在getTask()方法中待任务的工作线程
  30. }
  31. }
  32. /** 从工作队列中取出一个任务,工作线程会调用此方法*/
  33. private synchronized Runnable getTask(int threadid) throws InterruptedException {
  34. while(workQueue.size() == 0) {
  35. if(isClosed) return null;
  36. System.out.println("工作线程"+threadid+"等待任务...");
  37. wait();             //如果工作队列中没有任务,就等待任务
  38. }
  39. System.out.println("工作线程"+threadid+"开始执行任务...");
  40. return (Runnable) workQueue.removeFirst(); //反回队列中第一个元素,并从队列中删除
  41. }
  42. /** 关闭线程池 */
  43. public synchronized void closePool() {
  44. if(! isClosed) {
  45. waitFinish();        //等待工作线程执行完毕
  46. isClosed = true;
  47. workQueue.clear();  //清空工作队列
  48. interrupt();        //中断线程池中的所有的工作线程,此方法继承自ThreadGroup类
  49. }
  50. }
  51. /** 等待工作线程把所有任务执行完毕*/
  52. public void waitFinish() {
  53. synchronized (this) {
  54. isClosed = true;
  55. notifyAll();            //唤醒所有还在getTask()方法中等待任务的工作线程
  56. }
  57. Thread[] threads = new Thread[activeCount()]; //activeCount() 返回该线程组中活动线程的估计值。
  58. int count = enumerate(threads); //enumerate()方法继承自ThreadGroup类,根据活动线程的估计值获得线程组中当前所有活动的工作线程
  59. for(int i =0; i < count; i++) { //等待所有工作线程结束
  60. try {
  61. threads[i].join();  //等待工作线程结束
  62. }catch(InterruptedException ex) {
  63. ex.printStackTrace();
  64. }
  65. }
  66. }
  67. /**
  68. * 内部类,工作线程,负责从工作队列中取出任务,并执行
  69. * @author sunnylocus
  70. */
  71. private class WorkThread extends Thread {
  72. private int id;
  73. public WorkThread(int id) {
  74. //父类构造方法,将线程加入到当前ThreadPool线程组中
  75. super(ThreadPool.this,id+"");
  76. this.id =id;
  77. }
  78. public void run() {
  79. while(! isInterrupted()) {  //isInterrupted()方法继承自Thread类,判断线程是否被中断
  80. Runnable task = null;
  81. try {
  82. task = getTask(id);     //取出任务
  83. }catch(InterruptedException ex) {
  84. ex.printStackTrace();
  85. }
  86. //如果getTask()返回null或者线程执行getTask()时被中断,则结束此线程
  87. if(task == null) return;
  88. try {
  89. task.run();  //运行任务
  90. }catch(Throwable t) {
  91. t.printStackTrace();
  92. }
  93. }//  end while
  94. }//  end run
  95. }// end workThread
  96. }

2.测试类

  1. package com.tdt.test;
  2. import com.tdt.impl.ls.ThreadPool;
  3. public class ThreadPoolTest {
  4. public static void main(String[] args) throws InterruptedException {
  5. ThreadPool threadPool = new ThreadPool(3); //创建一个有个3工作线程的线程池
  6. Thread.sleep(500); //休眠500毫秒,以便让线程池中的工作线程全部运行
  7. //运行任务
  8. for (int i = 0; i <=5 ; i++) { //创建6个任务
  9. threadPool.execute(createTask(i));
  10. }
  11. threadPool.waitFinish(); //等待所有任务执行完毕
  12. threadPool.closePool(); //关闭线程池
  13. }
  14. private static Runnable createTask(final int taskID) {
  15. return new Runnable() {
  16. public void run() {
  17. //  System.out.println("Task" + taskID + "开始");
  18. System.out.println("Hello world");
  19. //  System.out.println("Task" + taskID + "结束");
  20. }
  21. };
  22. }
  23. }

结果:

  1. 工作线程0等待任务...
  2. 工作线程1等待任务...
  3. 工作线程2等待任务...
  4. 工作线程0开始执行任务...
  5. Hello world
  6. 工作线程0等待任务...
  7. 工作线程1开始执行任务...
  8. Hello world
  9. 工作线程1等待任务...
  10. 工作线程2开始执行任务...
  11. Hello world
  12. 工作线程2等待任务...
  13. 工作线程0开始执行任务...
  14. Hello world
  15. 工作线程0等待任务...
  16. 工作线程1开始执行任务...
  17. Hello world
  18. 工作线程1等待任务...
  19. 工作线程2开始执行任务...
  20. Hello world
  21. 工作线程2等待任务...

创建Java线程池的更多相关文章

  1. 按照阿里巴巴规范创建Java线程池

    前言 Executors Executors 是一个Java中的工具类.提供工厂方法来创建不同类型的线程池. 常用方法: 1.newSingleThreadExecutor   介绍:创建一个单线程的 ...

  2. Java线程池应用

    Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThread ...

  3. Java线程池七个参数详解

    Java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释. 从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize.maximumPoolS ...

  4. 使用Java 线程池的利弊及JDK自带六种创建线程池的方法

    1. 为什么使用线程池 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协 ...

  5. Java多线程01(Thread类、线程创建、线程池)

    Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...

  6. java线程池之一:创建线程池的方法

    在Java开发过程中经常需要用到线程,为了减少资源的开销,提高系统性能,Java提供了线程池,即事先创建好线程,如果需要使用从池中取即可,Java中创建线程池有以下的方式, 1.使用ThreadPoo ...

  7. java线程池及创建多少线程合适

    java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...

  8. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

  9. Java线程池使用说明

    Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...

随机推荐

  1. (转载)C++:STL标准入门汇总

    (转载)http://www.cnblogs.com/shiyangxt/archive/2008/09/11/1289493.html 学无止境!!! 第一部分:(参考百度百科) 一.STL简介 S ...

  2. 使用VisualStudio进行单元测试之一

    使用VisualStudio中的单元测试功能,可以很方便的创建单元测试项目.编写单元测试代码以及执行单元测试.而如何在VisualStudio中使用单元测试功能,就是本文和后面几篇想要说的了.    ...

  3. 《C语言程序设计现代方法》第4章 表达式

    C语言的一个特点就是它更多地强调表达式而不是语句,表达式是表示如何计算值的公式. 当表达式包含两个或更多个相同优先级的运算符时,运算符的结合性(associativity)开始发挥作用.如果运算符是从 ...

  4. JavaScript高级程序设计22.pdf

    操作节点 appendChild()用于向childNodes列表末尾添加一个节点,appendChild()返回新增的节点 var returnedNode=someNode.appendChild ...

  5. Android 播放视频并获取指定时间的帧画面

    最近做的项目要求既能播放视频(类似于视频播放器),又能每隔1s左右获取一帧视频画面,然后对图片进行处理,调查了一周,也被折磨了一周,总算找到了大致符合要求的方法.首先对调查过程中涉及到的方法进行简单介 ...

  6. 基于UDP协议的控制台聊天

    这几天学了java的网络编程弄出一个基于UDP协议的聊天工具 功能 添加并且备注好友(输入对方的ip) 删除好友 查看好友列表 用java写的控制台程序导出可执行程序后不能双击打开 还需要些一个脚本文 ...

  7. Closure Compiler(封闭编辑器), Closure Inspector, Closure Templates, 封闭图书馆(Closure Library) Google- 摘自网络

    谷歌日前宣布,将自己开发者使用的一系列工具对外开放.这些工具曾用来开发谷歌的主要产品,包括Gmail.谷歌文档(Google Docs)和谷歌地图(Google Maps). 第一个工具叫做Closu ...

  8. python Day 1 - 搭建开发环境

    搭建开发环境 首先,确认系统安装的Python版本是2.7.x: $ python --version Python 2.7.5 然后,安装开发Web App需要的第三方库: 前端模板引擎jinja2 ...

  9. Android MediaPlayer Error/Info Code

    1. 常见错误 error(-38, 0) 我觉得-38表示在当前的MediaPlayer状态下,不能运行你的操作. 详细怎样做请參考:Android MediaPlayer 另外我在其它资料中.发现 ...

  10. mybatis10 实现类代理对象开发

    mapper实现类代理对象开发 要想让mybatis自动创建dao接口实现类的代理对象,必须遵循一些规则: SqlSession sqlSession = sqlSessionFactory.open ...