简单线程池实现原理

一对线程解

       在平时工作中肯定会遇到关于线程的问题,在日常工作中,我们创建线程一般都是两种方式,实现Runnable接口或者继承thread类,这两种方式看过源码的都知道,其实Thread 也是实现Runnable接口。区别就是运行的过程有点不一样,因为线程运行最后都需要调用thread的run方法,如果是直接继承thread,thread里面的run方法被重写,就调用子类的run模块,如果是实现Runnable接口,则需要把实现Runnable 类的实例,传给thread类并且调用thread的run方法,这感觉有点像我学习中的简单代理模式。thread和实现Runnable 类的类都实现Runnable接口,thread 还代理运行实现Runnable 类的实例的方法。thread源码如下

                                     

再看看实现runable接口实例调用run方法,

                                 

这里也是学习过程中遇到的记录下来。

二线程池的理解

       创建线程任务的时候,不管以哪种方式,都是可以的 ,看你个人喜欢,但是当遇到成千上万的请求的时候,如果我么面对每一次请求都创建一个线程,那得 耗多少内存,浪费多少资源,请求速度也很慢,如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。

     所以有没有一个方法来解决这个问题呢,让线程可以重复使用,所有的请求都按照顺序存放在一个队里里,批次处理请求。

线程池就是这种解决方案。

三具体代码实现

package thread
;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;

public class ThreadPool   {
      private WorkThread[] workThread ;
    //public  static Thread1 t1=null;
    public LinkedList<Runnable> taskQueue= new LinkedList<Runnable>();//存放任务线程的队列
    public ThreadPool(){//当类实例化的时候会创建五个工作线程,用来工作
        this(5);
        
    }
    private ThreadPool(int num){
        workThread=new WorkThread[num];
        for(int i=0;i<num;i++){
            workThread[i]=new WorkThread();
            workThread[i].start();
        }
        
    }
  public void addThread(Runnable[] task){//把任务线程添加到队列里,等待执行
      synchronized (taskQueue) {//添加任务的时候释放队列锁
          for(Runnable r:task){
              taskQueue.add( r);
              taskQueue.notify();
          }
    }
      
  }
      public static void main(String[] args) {
    /*      Thread2 t2=new Thread1().new Thread2();
          Thread3 t3=new Thread1().new Thread3();
          t2.start();
          t3.start();*/
          
          ThreadPool t=new ThreadPool(2);
          t.addThread(new Runnable [] {new ThreadPool().new task(),new ThreadPool().new task(),new ThreadPool().new task2()} );//添加任务
       }
   public class WorkThread extends Thread{//五个工作线程,分别调用任务线程的run 方法,因为队列里面存放的是任务线程的实例
       private boolean isAlive=true;
       private Runnable r=null;
       
        public void run() {
              while(isAlive){
                  
                  synchronized(taskQueue){
                      while(isAlive&&taskQueue.isEmpty()){//如果队列还没有任务线程,工作线程会一直等待,直到有任务的时候工作
                          try {
                            taskQueue.wait(2000);//线程上锁时间
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                      } 
                      r=taskQueue.remove(0);//执行完一个任务就移除
                      if(r!=null){
                         r.run(); 
                      }
                  }
                
                
                  r=null;
              }
        }
        
    }
    
   public class task  implements Runnable{//任务线程,会被实例化放到队列里面
       
       public  void run(){
           System.out.println("1111");
           SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
           System.out.println(df.format(new Date()));// new Date()为获取当前系统时间
       }
       
   }
   
 public class task2  implements Runnable{//任务线程,会被实例化放到队列里面
       
       public  void run(){
           System.out.println("222");
           try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
           SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
           System.out.println(df.format(new Date()));// new Date()为获取当前系统时间
       }
       
   }
}
我总结的线程池实现思想是。创建五个工作线程,这个五个工作线程会一直等待并且执行队列里的任务,即调用任务线程的run方法。不再像传统的,创建一个线程就立马调用run方法。线程池把这个调用run的方法让工作线程来控制了,这样不管多少任务,多少请求(每一个任务每一个请求都是一个线程),每次只能完成五个。

  这是我理解的线程池实现原理,至于其他的 ,比如jdk 中使用的线程池,四种实现方式应该是在这个基础上加以改良,做各种限制操作等。

猜你喜欢

转载自blog.csdn.net/L_Mr_l/article/details/81180387
今日推荐