欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程池实例:继承ThreadGroup

程序员文章站 2022-05-29 13:25:07
...

 

线程池的作用:

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

 

为什么要用线程池:

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

相关标签: 线程池