ホームページ  >  記事  >  Java  >  Javaスレッドプールキューで遅延キューDelayQueueを使用する方法

Javaスレッドプールキューで遅延キューDelayQueueを使用する方法

WBOY
WBOY転載
2023-04-14 21:22:011197ブラウズ

ブロッキング キューでは、要素の追加と削除に加えて、要素の削除を遅らせることができます。つまり、DelayQueue メソッドを使用します。この記事では、Java スレッド プール キューの DelayQueue について説明します。 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

は、PriorityBlockingQueue に似ており、バイナリ ヒープ キューによって実装される無制限の優先度ブロックの実装です。すべての要素は Delayed インターフェイスを実装する必要があり、タスク 遅延を実行することによってキューから抽出されます。要素は遅延の期限が切れた後にのみキューから抽出できます。 DelayQueue の汎用パラメータは Delayed インターフェイスを実装する必要があります。Delayed インターフェイスは Comparable インターフェイス を継承します。DelayQueue は内部的に非スレッド セーフの優先キュー (PriorityQueue) を使用し、リーダー/フォロワー モードを使用して不要なインターフェイスを最小限に抑えます待ち時間。 。 DelayQueue には null 要素を含めることはできません。

public interface Delayed extends Comparable<Delayed> {

    /**
     * 返回与此对象关联的剩余延迟(给定的时间单位)。
     * @param unit 时间单位
     * @返回剩余延迟;零值或负值表示 延迟已过期
     */
    long getDelay(TimeUnit unit);
}

DelayQueue の使用シナリオ

キャッシュ システム設計: DelayQueue を使用してキャッシュ要素の有効期間を保存し、スレッドを使用してループ内で DelayQueue をクエリできます。 DelayQueue から要素を取得できた場合は、キャッシュの有効期限が切れたことを意味します。

タイミング タスク スケジューリング: DelayQueue を使用して、その日に実行されるタスクと実行時間を保存します。タスクが DelayQueue から取得されると、実行されます。例: TimerQueue DelayQueueを使用して実装されます。

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 構築方法

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

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

Delayed インターフェースの実装使用例

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 の概要

DelayQueue は実際に使用します

Decorator モード は、PriorityQueue のパッケージ化に 遅延時間取得要素 関数を追加します。その主な機能は次のように要約されます:

  • DelayQueue無制限のブロッキング キュー。PriorityQueue は、キュー内で実装するために使用されます。

  • #キューに入る要素は、Delayed インターフェイスを実装する必要があります。要素を作成するときに、プロパティを取得するのにかかる時間を指定できます。キューの現在の要素。遅延の有効期限が切れたときにのみ要素を抽出できる場合のみ
  • キューの先頭は、遅延の有効期限が切れた後の保存時間が最も長い遅延要素です。
  • 期限切れになっていない要素を遅延させず、キューにヘッドがなく、ポーリングで null が返される場合、
  • getDelay(TimeUnit.NANOSECONDS) の場合要素のメソッドが 0 以下の値を返します。これは、要素が期限切れであることを意味します
  • poll または take を使用して期限切れになっていない要素を削除することはできず、これらの要素は処理されません通常の要素として; 例: size メソッドは期限切れおよび期限切れでない要素を返します 要素数の合計
  • このキューでは null 要素は許可されません

以上がJavaスレッドプールキューで遅延キューDelayQueueを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。