基于 redis实现含有冻结时间的mq队列

来源:互联网 发布:字符能遍历吗python 编辑:程序博客网 时间:2024/06/06 06:34
redis自定义延时-mq.vsdx一、核心API

java延时队列  Delayed 
public interface RedisDelayed extends Delayed {
    public String toMessage();
}
自定义 java线程池  CountableThreadPool
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 计数线程池
 */
public class CountableThreadPool {

    /**
     * 线程数
     */
    private int threadNum;
 /** 
*
 *
 * 一个提供原子操作的Integer的类。
*  在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。
*  而AtomicInteger则通过一种线程安全的加减操作接口。
**/
    private AtomicInteger threadAlive = new AtomicInteger();

    private ReentrantLock reentrantLock = new ReentrantLock();

    private Condition condition = reentrantLock.newCondition();

    private ExecutorService executorService;

    /**
     * 
     * @param threadNum
     *            线程数
     */
    public CountableThreadPool(int threadNum) {
        this.threadNum = threadNum;
        this.executorService = Executors.newFixedThreadPool(threadNum);
    }

    public CountableThreadPool(int threadNum, ExecutorService executorService) {
        this.threadNum = threadNum;
        this.executorService = executorService;
    }

    public void setExecutorService(ExecutorService executorService) {
        this.executorService = executorService;
    }

    /**
     * 活动线程数
     * 
     * @return
     */
    public int getThreadAlive() {
        return threadAlive.get();
    }

    public int getThreadNum() {
        return threadNum;
    }

    public void execute(final Runnable runnable) {

        // 等待线程池中的名额
        if (threadAlive.get() >= threadNum) {//当运行中的线程大于线程池设定的线程数时,进入等待状态。
            try {
                reentrantLock.lock();
                while (threadAlive.get() >= threadNum) {//双层判定,你懂得
                    try {
                        condition.await();//进入等待状态,不继续执行 runnable内容
                    } catch (InterruptedException e) {
                    }
                }
            } finally {
                reentrantLock.unlock();
            }
        }
        threadAlive.incrementAndGet();//原子性递增
        executorService.execute(new Runnable() {
            public void run() {
                try {
                    runnable.run();
                } finally {
                    try {
                        reentrantLock.lock();
                        threadAlive.decrementAndGet();//原子性递递减
                        condition.signal();//唤醒第一个正在等待(被阻塞)的线程
                    } finally {
                        reentrantLock.unlock();
                    }
                }
            }
        });
    }

    public boolean isShutdown() {
        return executorService.isShutdown();
    }

    public void shutdown() {
        executorService.shutdown();
    }

}


java  延时队列 DelayQueue<T extends Delayed> ()     ,自定义延时队列的实现类,使用redis sortSet的api实现poll、add、iterator等操作。
                     
redis api 
redis zset 数据类型      zadd 、zrangeByScore 

二、流程图
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鼻子总感觉堵塞怎么办 半边鼻子不通气怎么办 鼻炎感冒了鼻塞怎么办 左边鼻子不通气怎么办 婴儿鼻塞不通气怎么办 过敏性鼻炎一直打喷嚏怎么办 一只鼻子流鼻涕怎么办 一个鼻子不通气怎么办 夏天鼻子堵了怎么办 做完鼻子感冒了怎么办 鼻子不通流鼻涕打喷嚏怎么办 一岁半宝宝流鼻涕鼻塞怎么办 没有感昌流鼻涕怎么办 婴儿感冒咳嗽流鼻涕怎么办 小孩经常流鼻子怎么办 5岁宝宝流鼻涕怎么办 小孩鼻涕一直流怎么办 二岁宝宝流鼻涕怎么办 小婴儿有点鼻塞怎么办 宝宝流鼻涕总不好怎么办 孩子鼻炎睡不好怎么办 鼻炎清鼻涕不止怎么办 宝宝持续低烧流鼻涕怎么办 孩子鼻塞不通气怎么办 2月婴儿感冒怎么办 长期流黄鼻涕怎么办 孩子流清水鼻涕怎么办 小孩有点流鼻子怎么办 初生婴儿堵鼻子怎么办? 小孩反复发烧了怎么办 小孩突然发烧了怎么办 40天宝宝鼻塞怎么办 宝宝伤风鼻子不通怎么办 鼻子伤风不通气怎么办 宝宝伤风流鼻子怎么办 十个月婴儿上火怎么办 一个多月宝宝鼻子有鼻屎怎么办 三个月婴儿感冒发烧怎么办 小孩感冒发烧流鼻涕怎么办 小孩感冒发烧反反复复怎么办 宝宝反复发烧39怎么办