Dalam baris gilir menyekat, selain menambah dan memadam elemen, kita boleh menangguhkan pemadaman elemen, iaitu menggunakan kaedah DelayQueue. Artikel ini akan bercakap dengan anda tentang DelayQueue dalam baris gilir benang Java - Delay Queue
public enum QueueTypeEnum { ARRAY_BLOCKING_QUEUE(1, "ArrayBlockingQueue"), LINKED_BLOCKING_QUEUE(2, "LinkedBlockingQueue"), DELAY_QUEUE(3, "DelayQueue"), PRIORITY_BLOCKING_QUEUE(4, "PriorityBlockingQueue"), SYNCHRONOUS_QUEUE(5, "SynchronousQueue"), LINKED_TRANSFER_QUEUE(6, "LinkedTransferQueue"), LINKED_BLOCKING_DEQUE(7, "LinkedBlockingDeque"), VARIABLE_LINKED_BLOCKING_QUEUE(8, "VariableLinkedBlockingQueue"), MEMORY_SAFE_LINKED_BLOCKING_QUEUE(9, "MemorySafeLinkedBlockingQueue"); }
adalah serupa dengan PriorityBlockingQueue, iaitu keutamaan tanpa had yang dilaksanakan oleh timbunan binari baris gilir menyekat Aras. Semua elemen diperlukan untuk melaksanakan antara muka Tertunda dan tugasan diekstrak daripada baris gilir dengan melaksanakan kelewatan hanya boleh diekstrak daripada baris gilir selepas kelewatan tamat. Parameter generik DelayQueue perlu melaksanakan antara muka Delayed mewarisi Antara muka Setanding menggunakan baris gilir keutamaan bukan benang-selamat (PriorityQueue) secara dalaman dan menggunakan mod Ketua/Pengikut untuk meminimumkan yang tidak perlu. masa menunggu. DelayQueue tidak dibenarkan mengandungi elemen null.
public interface Delayed extends Comparable<Delayed> { /** * 返回与此对象关联的剩余延迟(给定的时间单位)。 * @param unit 时间单位 * @返回剩余延迟;零值或负值表示 延迟已过期 */ long getDelay(TimeUnit unit); }
Reka bentuk sistem cache: DelayQueue boleh digunakan untuk menyimpan tempoh sah elemen cache dan urutan boleh digunakan untuk menanyakan DelayQueue dalam gelung Sebaik sahaja ia boleh diambil daripada DelayQueue Apabila elemen diperoleh, ia bermakna tempoh sah cache telah tamat.
Penjadualan tugasan masa: Gunakan DelayQueue untuk menyimpan tugasan dan masa pelaksanaan yang akan dilaksanakan pada hari tersebut Setelah tugasan diperoleh daripada DelayQueue, ia akan dilaksanakan sebagai contoh, TimerQueue dilaksanakan menggunakan DelayQueue.
//可重入同步锁 private final transient ReentrantLock lock = new ReentrantLock(); //DelayQueue的实现依赖于PriorityQueue(优先队列) private final PriorityQueue<E> q = new PriorityQueue<E>(); //第一个等待某个延时对象的线程,在延时对象还没有到期时其他线程看到这个leader不为null,那么就直接wait //主要是为了避免大量线程在同一时间点唤醒,导致大量的竞争,反而影响性能 private Thread leader = null; //条件队列,用于wait线程 private final Condition available = lock.newCondition();
//从上面属性就可以看出,DelayQueue采用了饿汉模式,调用构造方法即创建了队列实例 public DelayQueue() {} /** * 创建一个DelayQueue,最初包含给定的Collection实例集合。 * @param c 最初包含的元素集合 */ public DelayQueue(Collection<? extends E> c) { this.addAll(c); }
class MyDelay<T> implements Delayed { long delayTime; // 延迟时间 long expire; // 过期时间 T data; public MyDelay(long delayTime, T t) { this.delayTime = delayTime; // 过期时间 = 当前时间 + 延迟时间 this.expire = System.currentTimeMillis() + delayTime; data = t; } /** * 剩余时间 = 到期时间 - 当前时间 */ @Override public long getDelay(TimeUnit unit) { return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } /** * 优先级规则:两个任务比较,时间短的优先执行 */ @Override public int compareTo(Delayed o) { long f = this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS); return (int) f; } @Override public String toString() { return "delayTime=" + delayTime + ", expire=" + expire + ", data=" + data; } } public class DelayQueueDemo { static BlockingQueue<Delayed> queue = new DelayQueue(); public static void main(String[] args) throws InterruptedException { queue.add(new MyDelay(8, "第一次添加任务")); queue.add(new MyDelay(3, "第二次添加任务")); queue.add(new MyDelay(5, "第三次添加任务")); while (!queue.isEmpty()) { Delayed delayed = queue.take(); System.out.println(delayed); } } }
DelayQueue sebenarnya menggunakan mod penghias, dan menambah fungsi pemerolehan masa tunda bagi elemen di bawah pembungkusan PriorityQueue Ciri utamanya diringkaskan seperti berikut:
DelayQueue ialah baris gilir sekatan tanpa had. Barisan gilir menggunakan PriorityQueue untuk melaksanakan
Elemen yang memasuki baris gilir mesti melaksanakan antara muka Tertunda berapa lama masa yang diperlukan untuk dialih keluar daripada baris gilir Dapatkan elemen semasa, yang mana elemen itu hanya boleh diekstrak apabila kelewatan tamat tempoh
Ketua baris gilir ialah elemen Tertunda yang mempunyai masa penyimpanan yang paling lama selepas kelewatan tamat
Jika tiada unsur tertunda yang belum tamat tempoh, dan baris gilir tiada kepala, dan tinjauan pendapat akan kembali batal
Apabila kaedah getDelay(TimeUnit.NANOSECONDS) sesuatu elemen mengembalikan nilai kurang daripada atau sama dengan 0 Apabila nilainya adalah, ia bermakna elemen itu telah tamat tempoh
Elemen yang belum tamat tempoh tidak boleh dialih keluar menggunakan tinjauan pendapat atau ambil, dan elemen ini tidak akan dianggap sebagai elemen biasa sebagai contoh: kaedah saiz mengembalikan Jumlah kiraan elemen yang telah tamat tempoh dan belum tamat tempoh
Baris gilir ini tidak benarkan unsur nol
Atas ialah kandungan terperinci Cara menggunakan baris gilir kelewatan DelayQueue dalam baris gilir kumpulan benang Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!