ThreadPoolExecutor

来源:互联网 发布:淘宝账号查看平衡网页 编辑:程序博客网 时间:2024/06/11 19:29

ThreadPoolExecutor(基于jdk1.6  主要看线程执行流程,不关注线程池状态等):

主要属性:

BlockingQueue<Runnable> workQueue:同步任务队列

ReentrantLock mainLock:同步锁 用于addIfUnderCorePoolSize等方法中 

HashSet<Worker> workers:执行任务的worker队列

volatile int   corePoolSize:核心线程数 (volatile:比synchronized稍弱的同步机制)

volatile int   maximumPoolSize:池内最大线程数

volatile int   poolSize :当前线程数

以及其它一些RUNNING等线程池状态属性

主要方法:

execute执行任务:

 public void execute(Runnable command) {

        if (command == null)
            throw new NullPointerException();
        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {   //addIfUnderCorePoolSize
            if (runState == RUNNING && workQueue.offer(command)) {
                if (runState != RUNNING || poolSize == 0)
                    ensureQueuedTaskHandled(command);
            }
            else if (!addIfUnderMaximumPoolSize(command))
                reject(command); // is shutdown or saturated
        }
    }

第一步:如果当前线程数大于等于corePoolSize则添加到任务队列即可--》之后线程执行任务都是从队列里取,若小与corePoolSize则执行addIfUnderCorePoolSize

addIfUnderCorePoolSize:加锁调用addThread方法

  private boolean addIfUnderCorePoolSize(Runnable firstTask) {
        Thread t = null;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (poolSize < corePoolSize && runState == RUNNING)
                t = addThread(firstTask);
        } finally {
            mainLock.unlock();
        }
        return t != null;
    }

addThread:创建线程并添加到workers队列中

 private Thread addThread(Runnable firstTask) {
        Worker w = new Worker(firstTask);
        Thread t = threadFactory.newThread(w);
        boolean workerStarted = false;
        if (t != null) {
            if (t.isAlive()) // precheck that t is startable
                throw new IllegalThreadStateException();
            w.thread = t;
            workers.add(w);
            int nt = ++poolSize;
            if (nt > largestPoolSize)
                largestPoolSize = nt;
            try {
                t.start();   //启动线程
                workerStarted = true;
            }
            finally {
                if (!workerStarted)
                    workers.remove(w);
            }
        }
        return t;
    }



重点看Worker对象d的run方法:

  public void run() {
            try {
                hasRun = true;
                Runnable task = firstTask;
                firstTask = null;
                while (task != null || (task = getTask()) != null) {//循环获取task 去执行
                    runTask(task);
                    task = null;
                }
            } finally {
                workerDone(this);
            }
        }
    }


重点:getTask:(死循环从workQueue获取任务,直到线程池可退出)

Runnable getTask() {
        for (;;) {
            try {
                int state = runState;
                if (state > SHUTDOWN)
                    return null;
                Runnable r;
                if (state == SHUTDOWN)  // Help drain queue
                    r = workQueue.poll();
                else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
                    r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
                else
                    r = workQueue.take();
                if (r != null)
                    return r;
                if (workerCanExit()) {
                    if (runState >= SHUTDOWN) // Wake up others
                        interruptIdleWorkers();
                    return null;
                }
                // Else retry
            } catch (InterruptedException ie) {
                // On interruption, re-check runState
            }
        }
    }


简陋的模拟ThreadPoolExecutor:


public class MyTheadPoolExecuter {


    public static void main(String[] args) {
        MyTheadPoolExecuter myTheadPoolExecuter = new MyTheadPoolExecuter(new LinkedBlockingQueue());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
        myTheadPoolExecuter.execute(new Schedual());
    }


    private BlockingQueue<Runnable> runnableQuquq;
    private HashSet<Worker> workers=new HashSet<Worker>();
    private ReentrantLock reentrantLock=new ReentrantLock();
    private Boolean isFirst=false;


    public  Runnable getRunnable(){
        Runnable runnable = null;
        try {
            for(;;){          //死循环
                runnable = runnableQuquq.poll(1, TimeUnit.SECONDS);    //没有元素的话    等待十秒
                System.out.println("runnable=========null     "+new Date());
                if(runnable!=null){
                    System.out.println("runnable!=null");
                    return runnable;
                } else{
                    return null;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return runnable;
    }


    public MyTheadPoolExecuter(BlockingQueue blockingQueue){
            this.runnableQuquq=blockingQueue;
    }
    public boolean execute(Runnable runnable){
         if(runnable!=null){
             try {
                 reentrantLock.lock();
                 if(isFirst==false){
                     isFirst=true;
                     Worker worker = new Worker();
                     worker.firstRunnable=runnable;
                     Thread thread = new Thread(worker);
                     thread.start();
                 } else{
                   return runnableQuquq.offer(runnable);
                 }
             } finally {
                 reentrantLock.unlock();
             }
         }
        return true;
    }


    class Worker implements Runnable{
        private Runnable firstRunnable;
        @Override
        public void run() {
            if(firstRunnable==null){
                System.out.println("Worker Thread is null");
            }
            firstRunnable.run();
            while((firstRunnable=getRunnable())!=null){
                firstRunnable.run();
            }


            System.out.println("end");
        }
    }
}



参考:http://www.cnblogs.com/exe19/p/5359885.html




原创粉丝点击