Cola de bloqueo (3) -DelayQueue

DelayQueue

La cola de bloqueo ilimitada que admite el acceso retrasado a los elementos se
implementa internamente mediante PriorityQueue y ReentrantLock.

public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
    implements BlockingQueue<E> {

    private transient  final ReentrantLock lock = new ReentrantLock();
    private transient  final Condition available = lock.newCondition();
    private final PriorityQueue<E> q = new PriorityQueue<E>();
    ...
}

Los elementos de la cola deben implementar la interfaz retardada, y la interfaz retardada hereda la interfaz Comparable. La razón es que los elementos internos de DelayQueue deben 排序ordenarse por prioridad de tiempo de vencimiento.

public interface Delayed extends Comparable<Delayed> {	
    long getDelay(TimeUnit unit);
}

Escenarios de aplicación

  • El diseño del sistema de caché: DelayQueue se puede usar para guardar el período de validez de los elementos de la caché, y se puede usar un hilo para consultar DelayQueue en un bucle. Una vez que los elementos se pueden obtener de DelayQueue, significa que el período de validez de la caché ha expirado .
  • Programación temporizada de tareas: Use DelayQueue para guardar las tareas que se ejecutarán en el día y el tiempo de ejecución. Una vez que las tareas se obtienen de DelayQueue, comenzarán a ejecutarse. Por ejemplo, TimerQueue se implementa mediante DelayQueue.

Implementar la interfaz retrasada

Paso 1: inicializar los datos básicos cuando se crea el objeto. Use el tiempo para registrar cuándo se retrasa el objeto actual hasta que se pueda usar, y use sequenceNumber para identificar la secuencia de elementos en la cola.

private static final AtomicLong sequencer = new AtomicLong(0);
ScheduledFutureTask(Runnable r, V result, long ns, long period) {
	super(r, result);
	this.time = ns;
	this.period = period;
	this.sequenceNumber = sequencer.getAndIncrement();
}

Paso 2: Implemente el método getDelay (de la interfaz Delayed) para devolver cuánto tiempo debe retrasarse el elemento actual, en nanosegundos.

public long getDelay(TimeUnit unit) {
	return unit.convert(time - now(), TimeUnit.NANOSECONDS);
}

El tercer paso: cómo implementar el método compareTo para especificar el orden de los elementos. Por ejemplo, deje que el que tenga el tiempo de retraso más largo se coloque al final de la cola.
Implementación del método compareTo

Cómo implementar la cola de bloqueo retrasada

Cuando el consumidor obtiene un elemento de la cola, si el elemento no alcanza el tiempo de retardo, el hilo actual se bloquea.
Implementar cola de bloqueo retrasado

La variable líder es un hilo que espera obtener el elemento principal de la cola.

  • ¡Si el líder! = nulo, lo que indica que ya hay un hilo esperando obtener el elemento principal de la cola. Por lo tanto, use el método await () para hacer que el hilo actual espere la señal.
  • Si líder == nulo, establezca el hilo actual en líder y use el método awaitNanos () para dejar que el hilo actual espere recibir una señal o espere un tiempo de retraso.

Supongo que te gusta

Origin blog.csdn.net/eluanshi12/article/details/85122718
Recomendado
Clasificación