线程池的作用:

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

 

为什么要用线程池:

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

线程池类

import java.util.LinkedList;  /** * @project LocationGateway * @author sunnylocus    * @verson 1.0.0 * @date   Aug 2, 2008 * @jdk    1.4.2 */
public class ThreadPool extends ThreadGroup {  private boolean isClosed = false;  //线程池是否关闭   private LinkedList workQueue;      //工作队列  private static int threadPoolID = 1;  //线程池的id  public ThreadPool(int poolSize) {  //poolSize 表示线程池中的工作线程的数量  super(threadPoolID + "");      //指定ThreadGroup的名称  setDaemon(true);               //继承到的方法,设置是否守护线程池  workQueue = new LinkedList();  //创建工作队列  for(int i = 0; i < poolSize; i++) {  new WorkThread(i).start();   //创建并启动工作线程,线程池数量是多少就创建多少个工作线程  }  }  /** 向工作队列中加入一个新任务,由工作线程去执行该任务*/  public synchronized void execute(Runnable task) {  if(isClosed) {  throw new IllegalStateException();  }  if(task != null) {  workQueue.add(task);//向队列中加入一个任务  notify();           //唤醒一个正在getTask()方法中待任务的工作线程  }  }  /** 从工作队列中取出一个任务,工作线程会调用此方法*/  private synchronized Runnable getTask(int threadid) throws InterruptedException {  while(workQueue.size() == 0) {  if(isClosed) return null;  System.out.println("工作线程"+threadid+"等待任务...");  wait();             //如果工作队列中没有任务,就等待任务  }  System.out.println("工作线程"+threadid+"开始执行任务...");  return (Runnable) workQueue.removeFirst(); //反回队列中第一个元素,并从队列中删除  }  /** 关闭线程池 */  public synchronized void closePool() {  if(! isClosed) {  waitFinish();        //等待工作线程执行完毕  isClosed = true;  workQueue.clear();  //清空工作队列  interrupt();        //中断线程池中的所有的工作线程,此方法继承自ThreadGroup类  }  }  /** 等待工作线程把所有任务执行完毕*/  public void waitFinish() {  synchronized (this) {  isClosed = true;  notifyAll();            //唤醒所有还在getTask()方法中等待任务的工作线程  }  Thread[] threads = new Thread[activeCount()]; //activeCount() 返回该线程组中活动线程的估计值。  int count = enumerate(threads); //enumerate()方法继承自ThreadGroup类,根据活动线程的估计值获得线程组中当前所有活动的工作线程  for(int i =0; i < count; i++) { //等待所有工作线程结束  try {  threads[i].join();  //等待工作线程结束  }catch(InterruptedException ex) {  ex.printStackTrace();  }  }  }  /** * 内部类,工作线程,负责从工作队列中取出任务,并执行 * @author sunnylocus */  private class WorkThread extends Thread {  private int id;  public WorkThread(int id) {  //父类构造方法,将线程加入到当前ThreadPool线程组中  super(ThreadPool.this,id+"");  this.id =id;  }  public void run() {  while(! isInterrupted()) {  //isInterrupted()方法继承自Thread类,判断线程是否被中断  Runnable task = null;  try {  task = getTask(id);     //取出任务  }catch(InterruptedException ex) {  ex.printStackTrace();  }  //如果getTask()返回null或者线程执行getTask()时被中断,则结束此线程  if(task == null) return;  try {  task.run();  //运行任务  }catch(Throwable t) {  t.printStackTrace();  }  }//  end while  }//  end run  }// end workThread
}  

2.测试类

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

结果:

工作线程0等待任务...
工作线程1等待任务...
工作线程2等待任务...  工作线程0开始执行任务...
Hello world
工作线程0等待任务...  工作线程1开始执行任务...
Hello world
工作线程1等待任务...  工作线程2开始执行任务...
Hello world
工作线程2等待任务...  工作线程0开始执行任务...
Hello world
工作线程0等待任务...  工作线程1开始执行任务...
Hello world
工作线程1等待任务...  工作线程2开始执行任务...
Hello world
工作线程2等待任务...  

JAVA 创建线程池相关推荐

  1. Java创建线程池的方式

    Java创建线程池的方式 文章目录 Java创建线程池的方式 一.通过Executors工厂方法创建 1.Executors.newSingleThreadExecutor() 2.Executors ...

  2. java创建线程池几种方式_java知识总结-创建线程池的6种方式

    一.创建线程池的6种方式: Executors.newCachedThreadPool(); 创建一个可缓存线程池,应用中存在的线程数可以无限大 Executors.newFixedThreadPoo ...

  3. Java创建线程池的几种方式

    方式一:继承Thread类 新建一个类并该类声明为Thread的子类. 这个子类应该重写run类的方法.例如,计算大于规定值的素数的线程可以写成如下: class PrimeThread extend ...

  4. java创建线程池几种方式_Java 创建线程池两种不同方法的比较

    用Java做抓取的时候免不了要用到多线程的了,因为要同时抓取多个网站或一条线程抓取一个网站的话实在太慢,而且有时一条线程抓取同一个网站的话也比较浪费CPU资源.要用到多线程的等方面,也就免不了对线程的 ...

  5. 为什么阿里Java规约禁止使用Java内置Executors创建线程池?

    IDEA导入阿里规约插件,当你这样写代码时,插件就会自动监测出来,并给你红线提醒. 告诉你手动创建线程池,效果会更好. 在探秘原因之前我们要先了解一下线程池 ThreadPoolExecutor 都有 ...

  6. 谈谈java的线程池(创建、机制)

    目录 Executors创建线程池默认方法 自定义线程池 Executors创建线程池默认方法 newFixedThreadPool()方法,该方法返回一个固定数量的线程池,该方法的线程数始终不变,当 ...

  7. executor线程池框架_如何使用Java 5 Executor框架创建线程池

    executor线程池框架 Java 5以Executor框架的形式在Java中引入了线程池,它允许Java程序员将任务提交与任务执行分离. 如果要使用Java进行服务器端编程,则线程池是维护系统可伸 ...

  8. 如何使用Java 5 Executor框架创建线程池

    Java 5以Executor框架的形式在Java中引入了线程池,它允许Java程序员将任务提交与任务执行分离. 如果要使用Java进行服务器端编程,则线程池是维护系统可伸缩性,鲁棒性和稳定性的重要概 ...

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

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

最新文章

  1. 不是不去爱,爱了也是一种伤害!
  2. 弃繁就简!一行代码搞定 Python 日志!
  3. 50行代码搞定无限滑动幻灯片
  4. 如何用c语言验证一个定理,验证动量定理方法一
  5. ubuntu下c 访问mysql_Ubuntu下用C语言访问MySQL数据库
  6. asp.net的快捷实用分页类
  7. java8中的接口与时间操作
  8. day7--pandas
  9. [读书笔记] 计算机组成原理 唐朔飞 (一)基本概念
  10. 【Linux的开胃小菜】基于Ubuntu搭建内网DNS服务器
  11. 利用场景法设计atm自动取款机的测试用例_黑盒测试之场景法
  12. 一步一步理解欧拉公式
  13. Linux中指令的前缀命令格式
  14. python爬取某网站视频
  15. Crime and Punishment
  16. 【神经网络】变分自编码大杂烩
  17. java 蓝牙打印_Android蓝牙打印机,带你真正了解各种打印格式
  18. iOS 支付宝好友分享
  19. 使用超临界二氧化碳进行精密表面清洁
  20. 匹兹堡计算机科学公司,UPitt的Computer Science「匹兹堡大学计算机科学系」

热门文章

  1. Constraint4:default约束
  2. java接口关于interface关键字
  3. PHP学习笔记6:面向对象的PHP
  4. 使用PHP处理POST上传时$_FILES数组为何为空
  5. 防火墙iptables之常用脚本
  6. 5.MySQL Cluster(MySQL集群)
  7. 第八章 用户方式中线程的同步(2)
  8. 步步为营 .NET 代码重构学习笔记 十一
  9. MySQL主从配置的一些总结
  10. 《HTML 5与CSS 3 权威指南(第3版·上册)》——3.2 新增的非主体结构元素