All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.core.queue.a.ConcurrentArrayQueue Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.queue.a;

import shz.core.lock.ReadWriteLockHolder;

import java.io.Serializable;
import java.util.NoSuchElementException;
import java.util.RandomAccess;

/**
 * 基于循环动态数组的队列
 */
public abstract class ConcurrentArrayQueue extends ReadWriteLockHolder implements RandomAccess, Serializable {
    private static final long serialVersionUID = 8816397923504057202L;
    protected static final int DEFAULT_CAPACITY = 8;
    protected int capacity, size, tail, head;

    ConcurrentArrayQueue(int capacity) {
        if (capacity < 1) throw new IllegalArgumentException();
        this.capacity = capacity + 1;
    }

    public final int size() {
        readLock.lock();
        try {
            return size;
        } finally {
            readLock.unlock();
        }
    }

    public final boolean isEmpty() {
        readLock.lock();
        try {
            return size == 0;
        } finally {
            readLock.unlock();
        }
    }

    public final void clear() {
        writeLock.lock();
        try {
            tail = head = 0;
            size = 0;
        } finally {
            writeLock.unlock();
        }
    }

    protected final void checkEmpty() {
        if (size == 0) throw new NoSuchElementException();
    }

    protected final void beforeOffer() {
        if (size == capacity - 1) {
            if (capacity == Integer.MAX_VALUE) throw new OutOfMemoryError();
            int newCap = capacity >= 64 ? capacity + (capacity >> 1) : capacity << 1;
            resize(newCap < 0 ? Integer.MAX_VALUE : newCap);
        }
    }

    protected abstract void resize(int capacity);

    protected final void afterOffer() {
        tail = (tail + 1) % capacity;
        ++size;
    }

    protected final void afterPoll() {
        setNull(head);
        head = (head + 1) % capacity;
        --size;
        reduce();
    }

    private void reduce() {
        if (capacity > 64) {
            int newCap = size + 1 + (size + 1 >> 1);
            if (newCap + (newCap >> 1) <= capacity) resize(newCap);
        } else if (size + 1 <= capacity >>> 2) resize(capacity >> 1);
    }

    protected abstract void setNull(int i);

    public final void removeTail() {
        writeLock.lock();
        try {
            if (size == 0) return;
            if (tail == 0) tail = capacity - 1;
            else --tail;
            setNull(tail);
            --size;
            reduce();
        } finally {
            writeLock.unlock();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy