`

线程池实例:继承ThreadGroup

    博客分类:
  • java
阅读更多

 

线程池的作用:

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

 

为什么要用线程池:

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

import java.util.LinkedList;


public class ThreadPool extends ThreadGroup{
 private boolean isClosed = false;           //线程池是否关闭
 private LinkedList<Runnable> workQueue;     //工作队列
 private static int threadPoolID = 1;        //线程池的id

 public ThreadPool(int poolSize){            //poolSize 表示线程池中的工作线程的数量
  super(threadPoolID+"");                  //指定ThreadGroup的名称
  setDaemon(true);                //继承到的方法,设置是否守护线程池
  workQueue = new LinkedList<Runnable>();     //创建工作队列
  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();
   }
  }
 }

 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();
    }
   }
  }
 }

 

 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));
  }
  System.out.println("......................................");
  threadPool.waitFinish();  //等待所有任务执行完毕
  threadPool.closePool();   //关闭线程池

  System.out.println("game over!");
 }
 
 private static Runnable createTask(final int taskID){
  return new Runnable(){
   public void run(){
    try {
     Thread.sleep(20);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println(taskID + ": Hello");
   }
  };
 }
}

分享到:
评论

相关推荐

    Java线程池文档

    Java代码中展示的`ThreadPool`类是作者实现的一个简单线程池示例,使用了`LinkedList`作为工作队列,`ThreadPool`类继承了`ThreadGroup`,这在JDK 1.4版本中是一种常见实现方式。但在JDK 1.5及以上版本,推荐使用`...

    SAMS Java Thread Programming

    2. **附录B:ThreadGroup API**(The ThreadGroup API) - **API介绍**:介绍`ThreadGroup`类API的基本信息。 - **功能特性**:总结`ThreadGroup`类的主要功能和特点。 - **使用场景**:列举`ThreadGroup`类在多...

    java多线程设计模式.docx

    - **实现Runnable接口**:Java提供了两种方式来创建线程,一种是继承Thread类,另一种是实现Runnable接口。如果选择实现Runnable接口,那么你的类可以同时继承其他类,因为Java不支持多重继承。实现Runnable接口后...

    JAVA多线程编程集合.pdf

    - Thread类的构造器包括:Thread(Runnable target)、Thread(Runnable target, String name)、Thread(ThreadGroup group, Runnable target)、Thread(ThreadGroup group, Runnable target, String name)、Thread...

    5_Executors源码阅读1

    - `threadFactory(ThreadGroup group, ThreadFactory threadFactory)`:创建一个定制的线程工厂,可以自定义线程组和线程工厂。 4. **Callable任务的转换** - `callable(Runnable task)`:将Runnable转换为...

    聊天室server(java)

    - **ThreadGroup的使用**:`Server`类中定义了一个`ThreadGroup`实例,名为`threadGroup`,用于统一管理所有客户端连接处理线程。这是实现高效并发处理的关键,确保了线程资源的合理分配与管理。 - **线程生命周期...

    Java多线程

    - `Thread(ThreadGroup group, Runnable target, String name, long stackSize)` **3. 启动线程** 启动线程是通过调用`Thread`对象的`start()`方法完成的。调用`start()`方法会创建一个新的执行线程,并使该线程...

    java程序设计于开发 第七讲 多线程

    线程组(ThreadGroup)是用来管理一组线程的容器,它自身也是线程。线程组可以包含子线程组,形成一个树形结构。线程组提供了线程的统计、监控和保护等功能,例如,可以一次性停止组内所有线程。 在实际编程中,...

    Java多线程自学笔记

    - 可以通过`ThreadGroup`类创建和管理线程组。 #### 十、线程池 - **线程池**: - 是一种管理线程的有效方式,可以复用线程,减少创建和销毁线程的开销。 - 常见的线程池包括`ExecutorService`接口和其实现类如...

    Java多线程程序设计详细解析.pdf

    Java中线程的创建主要有两种方式,一种是继承Thread类,另一种是实现Runnable接口。在上述内容中,定义了一个继承自Thread类的MyThread类,并在构造函数中传递了编号作为线程的标识。通过覆写Thread类的run()方法来...

    北京恒华科技校园招聘Java Web开发工程师笔试题

    - **继承Thread类**:创建新的Thread类并重写run()方法。 - **实现Runnable接口**:创建类实现Runnable接口,重写run()方法,然后在Thread构造函数中传入实现Runnable的实例。 - **使用Callable和FutureTask**:...

    C#面试题目 超全超经典

    - **继承与多态**:理解单一继承和接口实现,以及多态的概念。 - **访问修饰符**:掌握public、private、protected、internal的用法。 - **抽象类与接口**:区别抽象类与接口,何时使用它们。 - **构造函数**:...

    java面试问题汇总(非常全面)

    - `Executor` 和 `ExecutorService`:用于管理和控制线程池。 - `ThreadFactory`:用于创建新的线程。 - `CountDownLatch`、`CyclicBarrier` 和 `Semaphore`:用于协调多个线程间的同步。 #### 3. 抽象类和接口的...

    java最新面试宝典

    - 创建线程的方式:继承`Thread`类与实现`Runnable`接口。 - `Callable`与`Future`的使用。 - 线程同步机制:`synchronized`关键字、`ReentrantLock`等。 - 线程池的创建与管理。 - **面试考察要点:** - 死锁...

    java线程源码-ng-javathread:该存储库是Nextgen关于学习Java线程的文章的源代码。请访问原始文章:

    最后,`java.lang.ThreadGroup`类是线程的容器,可以用来组织和管理线程。它可以用于设置线程的优先级、检查线程状态,甚至杀死线程。 总结起来,Java线程源码的学习涵盖了线程的创建、管理、同步和通信等多个方面...

    android知识点整理

    - **Thread和Service的区别**:Thread是执行任务的线程,而Service是Android四大组件之一。 - **线程同步和安全**:使用synchronized关键字或Lock对象保证线程安全。 - **IntentService和Service的区别**:...

    Java的作业调度类库Quartz基本使用指南

    这个配置文件定义了Scheduler的实例名称,是否启用RMI,线程池的类、线程数量、优先级以及线程是否继承初始化线程的类加载器。 总之,Quartz为Java开发者提供了一套强大的工具,可以方便地创建、管理和执行定时任务...

    java面试题-外企软件工程师面试题大全.rar

    4. 学习线程池的使用,如ExecutorService和ThreadPoolExecutor,以及线程池的参数配置。 五、I/O与NIO 1. 分析Java传统I/O(-blocking I/O)与非阻塞I/O(New IO, NIO)的区别。 2. 掌握FileInputStream、...

    NA3CGroup5CaseStudy:这是针对LAB考试和案例研究的

    通过实现Runnable接口或继承Thread类,你可以创建并管理自己的线程。并发编程时,理解锁(synchronized关键字)、条件变量(wait()和notify()方法)以及线程池(ExecutorService)的概念是必要的。 对于网络编程,...

Global site tag (gtag.js) - Google Analytics