BlockingQueue&ThreadFactory&RejectedExecutionHandler

BlockingQueue

阻塞队列接口,继承Queue接口,是一个先进先出的队列,提供阻塞获取和添加元素的方法

public interface BlockingQueue<E> extends Queue<E> {
	//抛出异常的获取方法
	boolean add(E e);
	boolean remove(Object o);
	E element();
	
	//不抛出异常的获取方法
	boolean offer(E e);
	E poll();
	E peek();
	
	//阻塞获取的方法
	E take() throws InterruptedException;
	void put(E e) throws InterruptedException;
	
	//阻塞直到成功或超时
	boolean offer(E e, long timeout, TimeUnit unit)
        throws InterruptedException;
        E poll(long timeout, TimeUnit unit)
        throws InterruptedException;

	//从该队列中删除所有可用的元素,并将它们添加到给定的集合中
	int drainTo(Collection<? super E> c);
	//返回该队列可以接受而不会阻塞的元素数量
	int remainingCapacity();
}

ArrayBlockingQueue有界队列

一个有界阻塞队列,底层采用数组实现,使用可重入锁(可选公平和非公平)和两个条件监视器来控制同步。对读写操作都加锁。

成员变量
//等待队列
final Object[] items;
//take, poll, peek or remove操作的下一次索引位置
int takeIndex;
//put, offer, or add操作的下一次索引位置
int putIndex;
//队列数量
int count;

//并发控制的锁和监视器
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
构造方法
//默认不公平锁
public ArrayBlockingQueue(int capacity) {
    this(capacity, false);
}

public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
   	//初始化数组大小、锁和监视器
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair);
    notEmpty = lock.newCondition();
    notFull =  lock.newCondition();
}
重要方法
enqueue(E x)

添加节点执行的操作

private void enqueue(E x) {
    // assert lock.getHoldCount() == 1;
    // assert items[putIndex] == null;
    final Object[] items = this.items;
    //在当前位置插入节点
    items[putIndex] = x;
    //当到达数组尾部,重新指向0位置,数组模拟队列操作
    //当putIndex =0时说明执行了出队操作,此时takeIndex指向1了
    if (++putIndex == items.length)
        putIndex = 0;
    count++;
    //唤醒所有在队列为空等待的线程
    notEmpty.signal();
}
dequeue()

删除节点执行的操作

private E dequeue() {
    // assert lock.getHoldCount() == 1;
    // assert items[takeIndex] != null;
    final Object[] items = this.items;
    @SuppressWarnings("unchecked")
    //获得旧值
    E x = (E) items[takeIndex];
    //删除位置设置为null
    items[takeIndex] = null;
    //当出队索引等于数组长度,索引重新指向0
    if (++takeIndex == items.length)
        takeIndex = 0;
    count--;
    if (itrs != null)
        itrs.elementDequeued();
    //唤醒所有在队列已满等待的线程
    notFull.signal();
    return x;
}

LinkedBlockingQueue无界队列

LinkedBlockingQueue是基于链表的无界队列(有最大值Integer.MAX_VALUE),不同于ArrayBlockingQueueQueue,LinkedBlockingQueue使用两个重入锁(非公平)来分别控制进队和出队操作,提高了吞吐量。

成员变量
//链表大小
private final int capacity;
//链表中元素个数(原子类)
private final AtomicInteger count = new AtomicInteger();
//链表的头结点(空节点)
transient Node<E> head;
//链表的尾结点
private transient Node<E> last;
//take, poll等操作的锁
private final ReentrantLock takeLock = new ReentrantLock();
//队列为空的等待监视器
private final Condition notEmpty = takeLock.newCondition();
//put, offer等操作的锁
private final ReentrantLock putLock = new ReentrantLock();
//队列已满的等待监视器
private final Condition notFull = putLock.newCondition();
构造方法
//默认初始大小为Integer.MAX_VALUE
public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);
}
//自定义初始大小
public LinkedBlockingQueue(int capacity) {
    if (capacity <= 0) throw new IllegalArgumentException();
    this.capacity = capacity;
    last = head = new Node<E>(null);
}
内部类Node

表示LinkedBlockingQueue队列中的节点,可以看出该队列为一个单向队列

static class Node<E> {
    E item;
    //队列中下一个元素
    Node<E> next;
    Node(E x) { item = x; }
}
重要方法
enqueue(Node node)

入队操作

private void enqueue(Node<E> node) {
    // assert putLock.isHeldByCurrentThread();
    // assert last.next == null;
    //将节点加入到尾结点的next节点上,并将尾结点设置为当前节点
    last = last.next = node;
}
dequeue()

出队操作

private E dequeue() {
    // assert takeLock.isHeldByCurrentThread();
    // assert head.item == null;
    //head节点为一个空节点,只有next有值
    Node<E> h = head;
    //移除头结点head节点
    Node<E> first = h.next;
    h.next = h; // help GC
    //将头结点设置为真实被移除节点,因为该节点item移除后为空
    head = first;
    E x = first.item;
    first.item = null;
    return x;
}
put(E e)
public void put(E e) throws InterruptedException {
    if (e == null) throw new NullPointerException();
    int c = -1;
    Node<E> node = new Node<E>(e);
    final ReentrantLock putLock = this.putLock;
    final AtomicInteger count = this.count;
    putLock.lockInterruptibly();
    try {
    	//如果队列中数量已满则挂起在notFull等待队列
        while (count.get() == capacity) {
            notFull.await();
        }
        //队列总添加节点
        enqueue(node);
        //c为队列数增加前的值
        c = count.getAndIncrement();
        //ArrayBlockingQueue中唤醒的notEmpty,此处唤醒notFull等待的线程,因为ArrayBlockingQueue入队出队共用一个锁。
        //也就是存在挂起在notFull的线程就一直添加节点
        if (c + 1 < capacity)
            notFull.signal();
    } finally {
        putLock.unlock();
    }
    //如果队列从空变为1则唤醒notEmpty中等待的线程
    if (c == 0)
        signalNotEmpty();
}
take()
public E take() throws InterruptedException {
    E x;
    int c = -1;
    final AtomicInteger count = this.count;
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lockInterruptibly();
    try {
    	//如果队列为空,则线程等待在notEmpty队列中
        while (count.get() == 0) {
            notEmpty.await();
        }
        //出队
        x = dequeue();
        c = count.getAndDecrement();
        //如果队列中有值且notEmpty中有线程阻塞,则一直出队
        if (c > 1)
            notEmpty.signal();
    } finally {
        takeLock.unlock();
    }
    //如果队列从满变为不满,则唤醒在notFull等待的线程
    if (c == capacity)
        signalNotFull();
    return x;
}

SynchronousQueue同步队列

无缓冲阻塞队列,该队列不存储元素,每个插入操作必须等待另一个线程调用移除操作,提供FIFO和LIFO两种模式,使用自旋+CAS来控制。

成员变量
//cpu数
static final int NCPUS = Runtime.getRuntime().availableProcessors();
//如果指定的timeout的自旋次数
static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
//未指定timeout的自旋次数
static final int maxUntimedSpins = maxTimedSpins * 16;
//指定timeout,自旋后剩余时间大于1000纳秒就挂起对应时间
static final long spinForTimeoutThreshold = 1000L;

//传输器
private transient volatile Transferer<E> transferer;
//同步操作使用可重入锁
private ReentrantLock qlock;
private WaitQueue waitingProducers;
private WaitQueue waitingConsumers;
构造方法
//默认采用LIFO模式
public SynchronousQueue() {
    this(false);
}
//指定队列是先进先出还是后进先出
public SynchronousQueue(boolean fair) {
    transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}
内部类
Transferer
/**
*@e:为空时表示需要消费数据(take),不为空表示生产数据(put)
*@timed:是否超时
*@nanos:超时时间,纳秒
*/
abstract static class Transferer<E> {
    abstract E transfer(E e, boolean timed, long nanos);
}
TransferStack

栈传输器

static final class TransferStack<E> extends Transferer<E> {
	//节点状态:消费者
    static final int REQUEST    = 0;
    //生产者
    static final int DATA       = 1;
	//正在互补匹配中
    static final int FULFILLING = 2;

	//栈的头结点
	volatile SNode head;

	static final class SNode {
            volatile SNode next;        // 栈中下一个节点
            volatile SNode match;       // 匹配,判断是否取消
            volatile Thread waiter;     // 等待的线程
            Object item;                // 数据
            int mode;					// 节点类型
     }
}
TransferQueue

队列传输器

static final class TransferQueue<E> extends Transferer<E> {
	//队列头结点
	transient volatile QNode head;
    //队列尾节点
    transient volatile QNode tail;

	//队列中节点
	static final class QNode {
            volatile QNode next;          // 下一个节点
            volatile Object item;         // 节点数据
            volatile Thread waiter;       // 等待线程
            final boolean isData;		  // 是否为数据节点
    }
}
重要方法
put(E e)

入队

public void put(E e) throws InterruptedException {
    if (e == null) throw new NullPointerException();
    //transfer方法返回null表示超时或中断
    if (transferer.transfer(e, false, 0) == null) {
        Thread.interrupted();
        throw new InterruptedException();
    }
}
take()

出队

public E take() throws InterruptedException {
    E e = transferer.transfer(null, false, 0);
    if (e != null)
        return e;
    Thread.interrupted();
    throw new InterruptedException();
}
transfer(E e, boolean timed, long nanos)
E transfer(E e, boolean timed, long nanos) {      
    SNode s = null; // constructed/reused as needed
    //如果e为null表示为消费者否则为生产者
    int mode = (e == null) ? REQUEST : DATA;
	//自旋
    for (;;) {
    	//获得栈的头结点
        SNode h = head;
        if (h == null || h.mode == mode) {  // 头为空或为相同模式
            if (timed && nanos <= 0) {      // 如果超时且已到期
                if (h != null && h.isCancelled()) // 如果h不为null,且h==match
                    casHead(h, h.next);     // 取消节点出队
                else
                	//超时返回null
                    return null;
            } else if (casHead(h, s = snode(s, e, h, mode))) { //设置头结点为新节点
                SNode m = awaitFulfill(s, timed, nanos); //阻塞当前入栈的线程并等待被匹配
                if (m == s) {               // m==s说明被取消了,返回null
                    clean(s);
                    return null;
                }
                //匹配成功, 如果头节点不为空,并且头节点的下一个节点是s
                if ((h = head) != null && h.next == s)
                    casHead(h, s.next);     // help s's fulfiller
                //根据当前节点的模式判断返回值
                return (E) ((mode == REQUEST) ? m.item : s.item);
            }
        } else if (!isFulfilling(h.mode)) { // 此处表示模式不同
            if (h.isCancelled())            // 头节点已被取消
                casHead(h, h.next);         // pop and retry
            //创建新节点并置为头节点,mode=11或10
            else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) {
                for (;;) { // 自旋直到匹配或线程中断
                    SNode m = s.next;       // m is s's match
                    if (m == null) {        // 表示栈中除了s都为空
                        casHead(s, null);   // pop fulfill node
                        s = null;           // use new node next time
                        break;              // restart main loop
                    }
                    SNode mn = m.next;
                    //将s设置为m的match,唤醒m处等待线程
                    if (m.tryMatch(s)) {
                        casHead(s, mn);     // s,m都出栈                      
                        //根据模式返回值
                        return (E) ((mode == REQUEST) ? m.item : s.item);
                    } else                  // lost match
                        s.casNext(m, mn);   // help unlink
                }
            }
        } else {                            // 头结点正在匹配中
            SNode m = h.next;               // m is h's match
            if (m == null)                  // waiter is gone
                casHead(h, null);           // pop fulfilling node
            else {
                SNode mn = m.next;
                if (m.tryMatch(h))          // 帮助尝试匹配
                    casHead(h, mn);         // pop both h and m
                else                        // lost match
                    h.casNext(m, mn);       // help unlink
            }
        }
    }
}

PriorityBlockingQueue优先队列

一个支持优先级的无界阻塞队列,但不能保证同优先级元素的顺序,底层采用二叉堆(数组,小顶堆)实现,使用可重入锁来控制入队出队。(如果不加比较器添加的元素必须继承Comparable接口)

成员变量
//默认容量
private static final int DEFAULT_INITIAL_CAPACITY = 11;
//最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//堆
private transient Object[] queue;
//堆大小
private transient int size;
//比较器
private transient Comparator<? super E> comparator;
//控制同步的锁
private final ReentrantLock lock;
//在为空时等待的监视器
private final Condition notEmpty;
//扩容时使用的自旋锁,通过CAS获取
private transient volatile int allocationSpinLock;
//非阻塞优先队列,用于序列化和反序列化
private PriorityQueue<E> q;
构造方法
//默认初始容量为11,比较器为null
public PriorityBlockingQueue() {
    this(DEFAULT_INITIAL_CAPACITY, null);
}
//指定初始大小和比较器
public PriorityBlockingQueue(int initialCapacity,
                             Comparator<? super E> comparator) {
    if (initialCapacity < 1)
        throw new IllegalArgumentException();
    //初始锁和监视器
    this.lock = new ReentrantLock();
    this.notEmpty = lock.newCondition();
    this.comparator = comparator;
    this.queue = new Object[initialCapacity];
}
重要方法
tryGrow(Object[] array, int oldCap)

对数组扩容,小于64扩容2倍+2,大于扩容1.5倍

private void tryGrow(Object[] array, int oldCap) {
    lock.unlock(); // 先释放offer中的重入锁
    Object[] newArray = null;
    //当allocationSpinLock为0且CAS修改其为1成功
    if (allocationSpinLock == 0 &&
        UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset,
                                 0, 1)) {
        try {
        	//如果旧容量小于64则扩容为old*2+2,否则扩容为1.5old
            int newCap = oldCap + ((oldCap < 64) ?
                                   (oldCap + 2) : // grow faster if small
                                   (oldCap >> 1));
            if (newCap - MAX_ARRAY_SIZE > 0) {    // 如果超出最大容量限制则为Integer.MAX_VALUE-8
                int minCap = oldCap + 1;
                if (minCap < 0 || minCap > MAX_ARRAY_SIZE)
                    throw new OutOfMemoryError();
                newCap = MAX_ARRAY_SIZE;
            }
            if (newCap > oldCap && queue == array)
                newArray = new Object[newCap];
        } finally {
            allocationSpinLock = 0;
        }
    }
    if (newArray == null) // 如果另外一个线程正在扩容,让出CPU控制权
        Thread.yield();
    lock.lock();
    //如果扩容了则将旧数组中的值复制到新数组上,queue == array避免多个线程复制旧数据
    if (newArray != null && queue == array) {
        queue = newArray;
        System.arraycopy(array, 0, newArray, 0, oldCap);
    }
}
offer(E e)
public void put(E e) {
    offer(e); //因为是无界的所以添加不阻塞
}
public boolean offer(E e) {
    if (e == null)
        throw new NullPointerException();
    final ReentrantLock lock = this.lock;
    lock.lock();
    int n, cap;
    Object[] array;
    //如果当前节点数大于容量则扩容
    while ((n = size) >= (cap = (array = queue).length))
        tryGrow(array, cap);
    try {
        Comparator<? super E> cmp = comparator;
        if (cmp == null)
            siftUpComparable(n, e, array);
        else
            siftUpUsingComparator(n, e, array, cmp);
        size = n + 1;
        //唤醒在队列为空等待的线程
        notEmpty.signal();
    } finally {
        lock.unlock();
    }
    return true;
}
siftUpComparable(int k, T x, Object[] array)

当没有比较器时,根据元素自身Comparable来插入堆中

private static <T> void siftUpComparable(int k, T x, Object[] array) {
	
    Comparable<? super T> key = (Comparable<? super T>) x;
    while (k > 0) {
    	//父节点位置
        int parent = (k - 1) >>> 1;
        Object e = array[parent];
        //如果如队数比父节点大则不用调整
        if (key.compareTo((T) e) >= 0)
            break;
        //否则调整堆
        array[k] = e;
        k = parent;
    }
    array[k] = key;
}
take()

元素出队

public E take() throws InterruptedException {
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    E result;
    try {
    	//如果队列为空线程阻塞
        while ( (result = dequeue()) == null)
            notEmpty.await();
    } finally {
        lock.unlock();
    }
    return result;
}
private E dequeue() {
	//元素出队位置
    int n = size - 1;
    //如果队列为空
    if (n < 0)
        return null;
    else {
        Object[] array = queue;
        //堆顶元素出队
        E result = (E) array[0];
        //获得堆尾元素
        E x = (E) array[n];
        array[n] = null;
        Comparator<? super E> cmp = comparator;
        //堆顶出队后调整堆
        if (cmp == null)
            siftDownComparable(0, x, array, n);
        else
            siftDownUsingComparator(0, x, array, n, cmp);
        size = n;
        return result;
    }
}

DelayQueue延迟队列

DelayQueue 是一个支持延时获取元素的阻塞队列,内部采用PriorityQueue存储元素,持有的元素必须继承Delay接口,在创建元素时可以指定多久才从队列中获得。

Delay接口
public interface Delayed extends Comparable<Delayed> {
	//在给定的时间单位中返回与此对象相关联的剩余延迟
    long getDelay(TimeUnit unit);
}
重要方法
offer(E e)

入队

public boolean offer(E e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        q.offer(e);
        //如果当前元素加入队列后在优先队列的头部
        if (q.peek() == e) {
            leader = null;
            //唤醒在空等待或在时延等待的线程
            available.signal();
        }
        return true;
    } finally {
        lock.unlock();
    }
}
take()
public E take() throws InterruptedException {
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
        for (;;) {
            E first = q.peek();
            //如果队列为空则阻塞
            if (first == null)
                available.await();
            else {
                long delay = first.getDelay(NANOSECONDS);
                if (delay <= 0)
                    return q.poll();
                first = null; // 如果队列头任然存在时延则阻塞
                //已有线程阻塞
                if (leader != null)
                    available.await();
                else {
                	//阻塞当前线程指定delay时间
                    Thread thisThread = Thread.currentThread();
                    leader = thisThread;
                    try {
                        available.awaitNanos(delay);
                    } finally {
                        if (leader == thisThread)
                            leader = null;
                    }
                }
            }
        }
    } finally {
        if (leader == null && q.peek() != null)
            available.signal();
        lock.unlock();
    }
}

ThreadFactory

ThreadFactory接口

线程工厂接口,提供获得线程的方法

public interface ThreadFactory {
	//工厂中获得线程的方法
    Thread newThread(Runnable r);
}

Executors中的默认工厂

Executors中的内部类

static class DefaultThreadFactory implements ThreadFactory {
    //区分不同线程工厂创建的线程
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    //线程组
    private final ThreadGroup group;
    //线程数量
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    //线程名前缀
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        //设置工厂线程组
        group = (s != null) ? s.getThreadGroup() :
                              Thread.currentThread().getThreadGroup();
        //线程名前缀,区分多个工厂生成的线程
        namePrefix = "pool-" +
                      poolNumber.getAndIncrement() +
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
    	//创建线程,赋予线程工厂的线程组,name=前缀+工厂中当前线程数
        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;
    }
}

RejectedExecutionHandler

拒绝策略接口

无法执行的任务的处理程序

public interface RejectedExecutionHandler {
	//当executor无法执行任务时可能调用的方法
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

AbortPolicy

ThreadPoolExecutor内部类,丢弃新任务,并抛出 RejectedExecutionException异常

public static class AbortPolicy implements RejectedExecutionHandler {
    public AbortPolicy() { }
    //丢弃任务,抛出异常信息:Task+任务toString+ rejected from +线程池toString(任务被线程池拒绝)
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                                             " rejected from " +
                                             e.toString());
    }
}

DiscardPolicy

ThreadPoolExecutor内部类,不做任何操作,直接丢弃新任务

public static class DiscardPolicy implements RejectedExecutionHandler {
        public DiscardPolicy() { }
		//不做任何操作
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

DiscardOldestPolicy

ThreadPoolExecutor内部类,丢弃队列队首的元素,并执行新任务

public static class DiscardOldestPolicy implements RejectedExecutionHandler {
    public DiscardOldestPolicy() { }

    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        //如果线程池未关闭
        if (!e.isShutdown()) {
        	//当前阻塞队列队首出队
            e.getQueue().poll();
            //执行新任务
            e.execute(r);
        }
    }
}

CallerRunsPolicy

ThreadPoolExecutor内部类,由调用线程执行新任务

public static class CallerRunsPolicy implements RejectedExecutionHandler {        
    public CallerRunsPolicy() { }

    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        //如果线程池未关闭
        if (!e.isShutdown()) {
            //由当前线程执行任务的run方法
            r.run();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值