线程池的基本实现

 阻塞队列

package org.butupi.pool;

import lombok.extern.slf4j.Slf4j;
import org.butupi.rejectPolicy.RejectPolicy;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 任务队列
 * @param 
 */
@Slf4j(topic = "TaskQueue")
public class BlockingQueue {

    // 1.任务队列
    private Deque queue = new ArrayDeque<>();

    // 2.锁,线程取任务时保护队列头和尾
    private ReentrantLock lock = new ReentrantLock();

    // 3.生产者条件变量
    private Condition fullWaitSet = lock.newCondition();
    // 4.消费者条件变量
    private Condition emptyWaitSet = lock.newCondition();

    // 5.容量
    private int capacity;

    /**
     * 构造器
     * @param capacity
     */
    public BlockingQueue(int capacity) {
        this.capacity = capacity;
    }

    /**
     * 阻塞获取任务
     * @return
     */
    public T take(){
        lock.lock();
        try {
            // 没有任务
            while (queue.isEmpty()){
                try {
                    // 阻塞等待任务
                    emptyWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 拿任务
            T t = queue.removeFirst();
            // 唤醒添加任务的线程
            fullWaitSet.signal();
            return t;
        }finally {
            lock.unlock();
        }
    }

    /**
     * 超时阻塞获取任务
     * @return
     */
    public T poll(long timeout, TimeUnit unit){
        lock.lock();
        try {
            long nanos = unit.toNanos(timeout);// 将timeout超时时间统一转换为纳秒
            // 没有任务
            while (queue.isEmpty()){
                try {
                    // 限时等待
//                    emptyWaitSet.await();
                    if (nanos <= 0){
                        return null;
                    }
                    nanos = emptyWaitSet.awaitNanos(nanos); // 返回的是剩余的时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 拿任务
            T t = queue.removeFirst();
            // 唤醒添加任务的线程
            fullWaitSet.signal();
            return t;
        }finally {
            lock.unlock();
        }
    }

    /**
     * 阻塞添加任务
     * @param task
     */
    public void put(T task){
        lock.lock();
        try {
            // 队列满,等待
            while (queue.size() == capacity){
                // 阻塞等待
                try {
                    log.info("等待加入任务队列:{}", task);
                    fullWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 添加到队列尾
            log.info("加入任务队列:{}", task);
            queue.addLast(task);
            // 唤醒拿任务的线程
            emptyWaitSet.signal();
        }finally {
            lock.unlock();
        }
    }

    /**
     * 向阻塞队列添加任务,超时等待
     * @param task
     * @param timeout
     * @param timeUnit
     * @return
     */
    public boolean offer(T task,long timeout, TimeUnit timeUnit){
        lock.lock();
        try {
            long nanos = timeUnit.toNanos(timeout);
            // 队列满,等待
            while (queue.size() == capacity){
                // 阻塞等待
                try {

                    log.info("等待加入任务队列:{}", task);
                    if (nanos <= 0){
                        return false;
                    }
                    nanos = fullWaitSet.awaitNanos(nanos);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 添加到队列尾
            log.info("加入任务队列:{}", task);
            queue.addLast(task);
            // 唤醒拿任务的线程
            emptyWaitSet.signal();
            return true;
        }finally {
            lock.unlock();
        }
    }

    /**
     * 获取任务的数量
     * @return
     */
    public int size(){
        lock.lock();
        try {
            return queue.size();
        }finally {
            lock.unlock();
        }
    }


    /**
     * 添加任务,的方法(拒绝策略
     * @param rejectPolicy
     * @param task
     */
    public void tryPut(RejectPolicy rejectPolicy, T task) {
        lock.lock();
        try {
            // 判断队列是否满
            if (queue.size() == capacity){
                // 拒绝策略
                rejectPolicy.reject(this,task);
            }else {
                // 队列空闲
                // 添加到队列尾
                log.info("加入任务队列:{}", task);
                queue.addLast(task);
                // 唤醒拿任务的线程
                emptyWaitSet.signal();
            }
        }finally {
            lock.unlock();
        }
    }
}

拒绝策略

package org.butupi.rejectPolicy;

import org.butupi.pool.BlockingQueue;

@FunctionalInterface
public interface RejectPolicy {
    void reject(BlockingQueue queue,T task);
}

线程池

package org.butupi.pool;

import javafx.concurrent.Worker;
import lombok.extern.slf4j.Slf4j;
import org.butupi.rejectPolicy.RejectPolicy;

import java.util.HashSet;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "c.ThreadPool")
public class ThreadPool {
    /**
     * 任务队列
     */
    private BlockingQueue taskQueue;

    /**
     * 线程集合
     */
    private HashSet workers = new HashSet();

    /**
     * 核心线程数
     */
    private int coreSize;

    /**
     * 超时时间
     */
    private long timeout;

    /**
     * 单位
     */
    private TimeUnit timeUnit;

    /**
     * 拒绝策略
     */
    private RejectPolicy rejectPolicy;


    /**
     * 线程池构造器
     *
     * @param coreSize
     * @param timeout
     * @param timeUnit
     * @param queueCapacity
     */
    public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapacity,RejectPolicy rejectPolicy) {
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.taskQueue = new BlockingQueue<>(queueCapacity);
        this.rejectPolicy = rejectPolicy;
    }

    /**
     * 执行任务
     *
     * @param task
     */
    public void execute(Runnable task) {
        synchronized (workers) {
            // 当任务数没有超过核心线程数时交给worker对象执行
            if (workers.size() < coreSize) {
                // 创建新的线程,把它添加到线程池workers中
                Worker worker = new Worker(task);
                log.info("新增 worker:{},任务:{}", worker, task);

                workers.add(worker);
                worker.start();
            } else {
                // 超过coreSize时,添加到任务队列
                // 1死等
//                taskQueue.put(task);
                // 2超时等待
                // 3放弃任务
                // 4主线程抛异常
                // 5调用者自己执行
                // 策略模式
                taskQueue.tryPut(rejectPolicy,task);

            }
        }

    }

    /**
     * 包装线程,有Worker包装Thread
     */
    class Worker extends Thread {
        private Runnable task;

        public Worker(Runnable task) {
            this.task = task;
        }

        @Override
        public void run() {

            // 执行任务
            // 1、task不为空,直接执行
            // 2、当task执行完毕,从任务队列获取任务执行
//            while (task != null || (task = taskQueue.take()) != null) {
            while (task != null || (task = taskQueue.poll(timeout,timeUnit)) != null) {
                try {
                    log.info("正在执行。。。{}", task);
                    task.run();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    task = null;
                }
            }

            // 移除此线程
            synchronized (workers) {
                log.info("worker:{} 被移除", this);
                workers.remove(this);
            }
        }
    }
}

测试类

(含拒绝策略的lambda表达式)

package org.butupi.pool;

import com.sun.org.apache.bcel.internal.generic.ATHROW;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

@Slf4j(topic = "c.TestPool")
public class Main {
    public static void main(String[] args) {
        ThreadPool threadPool = new ThreadPool(2, 1000, TimeUnit.MILLISECONDS, 10,
                // 死等
//                BlockingQueue::put
                // 超时等待
//                ((queue, task) -> queue.offer(task,1000,TimeUnit.MILLISECONDS))
                // 放弃任务执行
//                (queue,task)->log.info("放弃任务{}执行",task)
                // 抛异常
//                ((queue, task) -> {throw new RuntimeException("任务执行失败 "+task);})
                // 调用者自己执行
                (queue, task) -> task.run()
        );
        for (int i = 0; i < 15; i++) {
            int j = i;
            threadPool.execute(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info("{}", j);
            });
        }
    }
}

你可能感兴趣的:(底层知识,java)