用Stack实现对多线程的管理范例

多线程就是并发技术,当线程数量超过一定数量时,系统响应就会变慢,所以就必须对线程数量进行控制,那么采用哪种控制方法呢?采用Stack类模仿堆栈,之所以说是模仿,就是因为Stack类毕竟不是真实的堆栈,push和pop操作也并非是真正的入栈和出栈操作!程序思路是创建一个线程池管理类ThreadPool类,这个类的作用是用于创建指定数量的工作线程并压入栈中,此外还负责唤醒线程进行工作(方法是performedWork(Object data)),还有一个将执行完任务的线程重新压入栈中的方法push(),在线程池类内部有一个嵌套的工作线程WorkerThread类,这个类就是具体负责执行任务的工作线程,但是任务的具体执行者是由接口Worker或继承了该接口的实际类完成的。这里有几个关键点,一个数据对象,在创建了线程但还没有传入data对象时线程是一直处于wait()阻塞状态中。只有通过wake(Object data)方法进行唤醒并工作。

例程如下:

package thread.test;


import java.util.Stack;


public class StackThread {
     static class WorkProcess implements Worker{
        @Override
        public void run(Object data) {
            System.out.println(data);
        }  
      }
     public static void main(String[] args) throws Exception {
                 WorkProcess wp=new WorkProcess(); 
                ThreadPool tp = new ThreadPool(wp.getClass(),10);
                 for(int i=0;i<11;i++)  //输出的顺序是没有先后的,第十一个线程为额外线程
              tp.performedWork("function#"+i);  
     }  
}
class ThreadPool{
      class WorkerThread extends Thread{
          private Object data;
          private Worker worker;
          //工作线程需要两个参数,标识符和工作接口,还需要一个数据用于运行run(Object data)方法,在得到data对象之前,线程一直处于阻塞状态
          public WorkerThread(String idoilt,Worker worker){
              super(idoilt);
              this.worker=worker; 
             data=null;
          }
         synchronized public void wake(Object data){
              this.data=data;
              this.notify();
         }
        @Override
        synchronized public void run(){
               boolean stop=false;
                while(!stop){
               if(data==null){
               try {
                       this.wait();
                } catch (InterruptedException e) {
                       e.printStackTrace();
                }
             }
            if(data!=null){ //下面这两句话可能不会同时输出,即线程会在输出第一句话之后切换到另外一个线程
               System.out.println(this.getName());
               worker.run(data);
          }
          data=null;
     stop=push(this);
          }  
         }
     }

      @SuppressWarnings("rawtypes")
         private Stack  _waiting;        //被所有线程所共享的对象,所以必须同步,用于存放所有的工作线程
      @SuppressWarnings("rawtypes")
      private Class  _workerClass;
      int _max;
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public ThreadPool(Class workerClass,int max)throws Exception{
     _workerClass=workerClass; 
     _max=max;
      _waiting =new Stack();
     Worker wo;
     WorkerThread wt;
     for(int i=0;i<_max;i++){//创建一定数量的工作线程
         wo=(Worker)_workerClass.newInstance(); //产生一个新的实例,均是继承于Worker接口。
         wt=new WorkerThread("worker#"+i,wo);
         wt.start();//请网友思考一下为什么这里要启动方法,而不在performedWork方法中启动呢?但实际确实必须在这里启动
        _waiting.push(wt);
      }
   }
    //执行工作线程方法,传入data对象唤醒线程进行工作
    public void performedWork(Object data)throws InstantiationException, IllegalAccessException{
         WorkerThread w= null;
         synchronized(_waiting){
           if(_waiting.empty()){
               w=new WorkerThread("addtional thread",
                           (Worker)_workerClass.newInstance());
                 w.start();
             }
            else {
                w=(WorkerThread)_waiting.pop();
               //w.start();  //这条语句是错的,会引发一个IllegalThreadStateException异常,具体原因我也不清楚,你想清楚了,可以告诉我
                //在这里启动可能就会导致wake方法失去意义,因为唤醒线程之前必须处于阻塞状态,也就是必须启动线程!在这里启动并不会立即启动
                //线程,而是会继续往下执行wake方法,由于线程未启动就唤醒就会出错! 
             }
  
             w.wake(data);

          }
     }
     @SuppressWarnings("unchecked")
      public boolean push(WorkerThread obj){
           boolean isPOP=false;
           synchronized(_waiting){
                   if(_waiting.size()<_max){
                          _waiting.push(obj);
                          isPOP=true;
                   }
               }
            return isPOP;
     }
}
interface Worker {
            public void run(Object data);
}
这辆直升机是九江红鹰制造的,确实非常不错,看起来真酷! 

 

posted @ 2013-06-17 21:58  爱生活,爱编程  阅读(410)  评论(0编辑  收藏  举报