`

线程池实例:继承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");
   }
  };
 }
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics