JAVA:二分练习——历届试题《区间位移》

老品牌万能阅读器,Calibre中文版(阅读转换)

  返回  

线程池ThreadPoolExecutor学习

2021/7/21 12:30:34 浏览:

构造方法

    public ThreadPoolExecutor(int corePoolSize, // 核心线程数量
                              int maximumPoolSize,// 最大线程数量
                              long keepAliveTime,// (Max-Core)线程存活时间 
                              TimeUnit unit,//时间单位
                              
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {

workQueue

一共有七种

SynchronousQueue

SynchronousQueue可以认为是一个缓存值为1的阻塞队列,但是 **isEmpty()**方法永远返回是true,remainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null。具体看源码。

// 构造方法有两个,默认是非公平模式
    public SynchronousQueue(boolean fair) {
        transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
    }

一个是TransferStack类,使用LIFO顺序存储元素,这个类用于非公平模式;还有一个类是TransferQueue,使用FIFI顺序存储元素,这个类用于公平模式。 具体可参考这个链接:简书

LinkedBlockingQueue

不指定容量的话就是无界队列(Integer.MAX_VALUE,约等于无界了)。注意点:1-当可以保证线程池的数据<CoreNumber的时候,是可以提升一定的性能。但是代价是牺牲内存,可能OOM。慎用无参构造

    public LinkedBlockingQueue(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node<E>(null);
    }

该类的大致结构
在这里插入图片描述

具体内容,可参考https://www.jianshu.com/p/9394b257fdde

ArrayBlockingQueue

有界队列,基于数组实现。在线程池初始化时,指定队列的容量。内部采用显式锁,两个锁条件。

PriorityBlockingQueue

支持优先级排序的无界阻塞队列。默认队列容量11
Object[] queue; 队列元素数组。平衡二叉堆实现,父节点下标是n,左节点则是2n+1,右节点是2n+2。最小的元素在最前面。
ALLOCATIONSPINLOCK:allocationSpinLock:扩容数组分配资源时的自旋锁,CAS需要

    // VarHandle mechanics
    private static final VarHandle ALLOCATIONSPINLOCK;
    static {
        try {
            MethodHandles.Lookup l = MethodHandles.lookup();
            ALLOCATIONSPINLOCK = l.findVarHandle(PriorityBlockingQueue.class,
                                                 "allocationSpinLock",
                                                 int.class);
        } catch (ReflectiveOperationException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
// 排序器若是不传,则默认是自然排序。元素E,必须实现Comparable
    public PriorityBlockingQueue(int initialCapacity,
                                 Comparator<? super E> comparator) {
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.comparator = comparator;
        this.queue = new Object[Math.max(1, initialCapacity)];
    }

DelayQueue

延迟队列。
DelayQueue延迟队列同时具备:无界队列、阻塞队列、优先队列的特征。分别来看下:
无界队列:通过调用DelayQueue的offer方法(或add方法),把待执行的任务对象放入队列,该方法是非阻塞的。这个队列是无界队列,内存足够的情况下,理论上存放的任务对象数是无限的。

阻塞队列:DelayQueue实现了BlockingQueue接口,是一个阻塞队列。但该队列只是在取对象时阻塞,对应两个方法:1、take()方法,获取并移除队列头的对象,如果时间还未到,就阻塞等待。2、poll(long timeout, TimeUnit unit) 方法,阻塞时间长度为timeout,然后获取并移除队列头的对象,如果对象延迟时间还未到,就返回null。

优先队列:DelayQueue的一个重要的成员是一个优先队列PriorityQueue,PriorityQueue内部是一个二叉小顶堆实现,其特点就是头部元素对应的权值是队列中最小的,也就是通过poll()方法获取到的对象是最优先的。

ThreadFactory

默认的线程工厂代码如下

DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

拒绝策略

当线程池workQueue已满且无法再创建新线程池时,就要拒绝后续任务了
AbortPolicy-默认
若此拒绝策略工作总会抛出:RejectedExecutionException。

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }

DiscardPolicy
直接丢弃任务,不抛出任何异常

        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号