java中的延迟队列(DelayQueue)

问:什么情况下用DelayQueue


答:比如说订单下单后15分钟过期、要触发一系列的逻辑处理。这时候我们就可以用DelayQueue来完成。



问:实现原理是什么呢?


答:请看代码~~!注:这里用redis来存储队列中的任务。代码是复制 java中 DelayQueue的源码改造的。



package com.coinex.common.concurrent;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.redisson.api.RPriorityQueue;
import org.redisson.api.RedissonClient;
import org.redisson.codec.SerializationCodec;

public class RedisDelayQueue extends AbstractQueue
implements BlockingQueue {

	
    private final transient ReentrantLock lock = new ReentrantLock();
    private  RPriorityQueue q = null;
    
    private Thread leader = null;
    
    private final Condition available = lock.newCondition();
    

    
    public RedisDelayQueue (RedissonClient redissonClient) {
    	SerializationCodec codec = new SerializationCodec();
    	q = redissonClient.getPriorityQueue("priority"+this.hashCode(),codec);
    }
	
	@Override
	public E poll() {
		return null;
	}

	@Override
	public E peek() {
		return null;
	}

	@Override
	public boolean offer(E e) {
        final Lock lock = this.lock;
        lock.lock();
        try {
            q.offer(e);
            if (q.peek().equals(e)) {
                leader = null;
                available.signal();
            }
            return true;
        } finally {
            lock.unlock();
        }
	}

	@Override
	public void put(E e) {
		 offer(e);
		
	}

	@Override
	public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
		 return offer(e);
	}

	@Override
	public E take() throws InterruptedException {
        final Lock lock = this.lock;
        lock.lockInterruptibly();
        try {
            for (;;) {
                E first = q.peek();
                if (first == null)
                    available.await();
                else {
                    long delay = first.getDelay(NANOSECONDS);
                    if (delay <= 0)
                        return q.poll();
                    first = null; 
                    if (leader != null)
                        available.await();
                    else {
                        Thread thisThread = Thread.currentThread();
                        leader = thisThread;
                        try {
                            available.awaitNanos(delay);
                        } finally {
                            if (leader == thisThread)
                                leader = null;
                        }
                    }
                }
            }
        } finally {
            if (leader == null && q.peek() != null)
                available.signal();
            lock.unlock();
        }
	}

	@Override
	public E poll(long timeout, TimeUnit unit) throws InterruptedException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int remainingCapacity() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int drainTo(Collection c) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int drainTo(Collection c, int maxElements) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Iterator iterator() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return 0;
	}

}

主要就是看task()方法的实现。这里用到一个模式。就是 Leader-Follower

你可能感兴趣的:(Java基础)