码迷,mamicode.com
首页 > 编程语言 > 详细

使用Lock(ReentrantLock)结合Condition实现自定义线程池

时间:2016-04-20 19:51:02      阅读:375      评论:0      收藏:0      [点我收藏+]

标签:

声明:

  1、该篇只是提供一种自定义线程池的实现方式,可能性能、安全等方面需要优化;

  2、该篇自定义线程池使用Lock(可重入锁ReentrantLock)结合Condition来实现;

  3、该篇力求使用简单的方式呈现,如有错误之处,欢迎指正,在此表示感谢。

概述

  自定义线程池三要素包括:

  1、存储线程的容器(或叫线程池)。该容器可使用数组或链表,容器中存放执行线程,本篇使用链表实现。

  2、执行线程(或叫执行器)。具体执行的线程。

  3、执行任务。执行线程需要执行的具体任务。

代码

/**
 * 任务接口
 *
 */
public interface Task {
    
    /**
     * 执行任务
     */
    void executeTask();

}
/**
 * 执行接口
 *
 */
public interface Executor {
    
    /**
     * 设置任务
     * 
     * @param task 任务
     */
    void setTask(Task task);
    
    /**
     * 获取任务
     * 
     * @returnTask
     */
    Task getTask();
    
    /**
     * 启动任务
     */
    void startTask();

}
/**
 * 线程池接口
 *
 */
public interface Pool {
    
    /**
     * 获取执行线程
     * 
     * @return Executor
     */
    Executor getExecutor();
    
    /**
     * 销毁线程池
     */
    void destory();

}
/**
 * 线程池实现类
 *
 */
public class ThreadPool implements Pool {
    
    //是否开启线程池,true-开启,false-关闭
    private boolean isOpen = true;
    
    //默认执行线程数量
    private final static int DEFAULT_THREAD_NUM = 6;
    
    //执行线程数量,默认为DEFAULT_THREAD_NUM
    private static int THREAD_NUM = DEFAULT_THREAD_NUM;
    
    //存放执行线程的容器
    private LinkedList<Executor> container = new LinkedList<Executor>();
    
    //可重入锁
    private Lock lock = new ReentrantLock();
    
    //condition
    private Condition condition = lock.newCondition();
    
    public ThreadPool(int threadNum){
        isOpen = true;
        THREAD_NUM = threadNum > 0 ? threadNum : THREAD_NUM;
        for(int i = 0;i < THREAD_NUM;i++){
            Executor executor = new ExecutorImpl();
            ((ExecutorImpl)executor).setName("执行线程" + i);
            container.add(executor);//将执行线程加入容器中
            ((ExecutorImpl)executor).start();//启动执行线程
        }
    }
    
    public ThreadPool(){
        this(DEFAULT_THREAD_NUM);
    }

    @Override
    public Executor getExecutor() {
        Executor executor = null;
        try{
            lock.lock();//加锁
            if(container.size() > 0){
                executor = container.removeFirst();
            }else{
                condition.await();//等待,释放锁
                executor = container.removeFirst();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            lock.unlock();//释放锁
        }
        return executor;
    }

    @Override
    public void destory() {
        try{
            lock.lock();//加锁
            isOpen = false;
            condition.signalAll();//通知
            container.clear();
        }finally{
            lock.unlock();//释放锁
        }

    }
    
    private class ExecutorImpl extends Thread implements Executor{
        
        //执行任务
        private Task task;
        
        //可重入锁
        private Lock innerLock = new ReentrantLock();
        
        //condition
        private Condition innerCondition = innerLock.newCondition();
        
        public void run(){
            while(isOpen){
                try{
                    System.out.println(Thread.currentThread().getName() + " 启动   <<<<<<<<");
                    innerLock.lock();;//加锁
                    System.out.println(Thread.currentThread().getName() + " 等待   >>>>>>>>");
                    innerCondition.await();//等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally{
                    innerLock.unlock();//释放锁
                }
                System.out.println(Thread.currentThread().getName() + " 执行任务  ........");
                getTask().executeTask();//执行任务
                //任务执行完,放回容器中
                try{
                    lock.lock();//加锁
                    //将该执行线程放回容器中
                    System.out.println(Thread.currentThread().getName() + " 返回容器  。。。。。。。。");
                    container.add(ExecutorImpl.this);
                    System.out.println(container);
                    condition.signalAll();//通知
                }finally{
                    lock.unlock();//释放锁
                }
            }
        }

        @Override
        public void setTask(Task task) {
            this.task = task;
        }

        @Override
        public Task getTask() {
            return this.task;
        }

        @Override
        public void startTask() {
            try{
                innerLock.lock();//加锁
                innerCondition.signal();//通知
            }finally{
                innerLock.unlock();//释放锁
            }
        }
        
    }

}
public class Test {
    
    public static void main(String[] args) throws InterruptedException {
        
        Pool pool = new ThreadPool(2);
        
        for(int i = 0;i < 2;i++){
            Executor executor = pool.getExecutor();
            Task task = new PrintTask();
            executor.setTask(task);
            executor.startTask();
        }
        
        pool.destory();
        
    }

}
执行线程0 启动   <<<<<<<<
执行线程1 启动   <<<<<<<<
执行线程1 等待   >>>>>>>>
执行线程0 等待   >>>>>>>>
执行线程0 执行任务  ........
执行线程0执行了打印任务
执行线程0 返回容器  。。。。。。。。
执行线程1 执行任务  ........
执行线程1执行了打印任务
[Thread[执行线程0,5,main]]
执行线程1 返回容器  。。。。。。。。
[Thread[执行线程0,5,], Thread[执行线程1,5,main]]

  

使用Lock(ReentrantLock)结合Condition实现自定义线程池

标签:

原文地址:http://www.cnblogs.com/wuq126/p/5413834.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!