Rumah  >  Artikel  >  Java  >  Cara menggunakan baris gilir kelewatan DelayQueue dalam baris gilir kumpulan benang Java

Cara menggunakan baris gilir kelewatan DelayQueue dalam baris gilir kumpulan benang Java

WBOY
WBOYke hadapan
2023-04-14 21:22:011128semak imbas

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");
}

DelayQueue Delay Queue

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);
}

Senario penggunaan DelayQueue

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.

Atribut 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();

Kaedah pembinaan DelayQueue

//从上面属性就可以看出,DelayQueue采用了饿汉模式,调用构造方法即创建了队列实例
public DelayQueue() {}

/**
 * 创建一个DelayQueue,最初包含给定的Collection实例集合。
 * @param c 最初包含的元素集合
 */
public DelayQueue(Collection<? extends E> c) {
    this.addAll(c);
}

Melaksanakan contoh penggunaan antara muka Tertunda

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);
        }
    }
}

Ringkasan DelayQueue

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!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam