Java多线程工具包java.util.concurrent---DelayQueue

延迟队列 DelayQueue

DelayQueue 实现了 BlockingQueue 接口。
DelayQueue 对元素进行持有直到一个特定的延迟到期。
DelayQueue 将会在每个元素的 getDelay() 方法返回的值的时间段之后才释放掉该元素。如果返回的是 0 或者负值,延迟将被认为过期,该元素将会在 DelayQueue 的下一次 take 被调用的时候被释放掉。
传递给 getDelay 方法的 getDelay 实例是一个枚举类型,它表明了将要延迟的时间段。

具体示例

本示例模拟session缓存数据为例。
延迟队列元素
正如你所看到的,Delayed 接口也继承了 java.lang.Comparable 接口,这也就意味着 Delayed 对象之间可以进行对比

class DelayElements implements Delayed {

        private String key;

        // 存活时间
        private long aliveTime;
        // 过期时间
        private long timeOut;

        public long getTimeOut() {
            return timeOut;
        }

        public void setTimeOut(long timeOut) {
            this.timeOut = timeOut;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public long getAliveTime() {
            return aliveTime;
        }

        public void setAliveTime(long aliveTime) {
            this.aliveTime = aliveTime;
        }

        public DelayElements(String key, long aliveTime) {
            super();
            this.key = key;
            this.aliveTime = aliveTime;
            this.timeOut = TimeUnit.NANOSECONDS.convert(aliveTime, TimeUnit.SECONDS) + System.nanoTime();
        }

        @Override
        public int compareTo(Delayed o) {
            if (o == null)
                return 1;
            if (o == this)
                return 0;
            if (o instanceof DelayElements) {
                DelayElements de = (DelayElements) o;
                if (this.timeOut > de.getTimeOut()) {
                    return 1;
                } else if (this.timeOut < de.getTimeOut()) {
                    return -1;
                }
            }
            return 0;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(timeOut - System.nanoTime(), TimeUnit.NANOSECONDS);
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((key == null) ? 0 : key.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            DelayElements other = (DelayElements) obj;
            if (key == null) {
                if (other.key != null)
                    return false;
            } else if (!key.equals(other.key))
                return false;
            return true;
        }


    }

Session类设计

class Session {
        /* 延迟时间,按照秒计算 */
        private static final int _aliveTime = 7;
        /* 延迟队列 */
        DelayQueue<DelayElements> queue = new DelayQueue<>();
        /* 模拟session存放信息,保证线程安全  */
        private ConcurrentHashMap<String, Object> userSession = new ConcurrentHashMap<>();
        public Session() {
        }

        public void put(String key, Object value) {
            // 放入session集合中
            userSession.put(key, value);
            // 构造延时列队元素
            DelayElements delayElements = new DelayElements(key, _aliveTime);
            // 移除之前的队列
            queue.remove(key);
            // 插入新的队列
            queue.add(delayElements);
            System.out.println("添加session key:" + key + ",value:" + value.toString() + "成功");
        }

        public Object get(String key){
            /*从session池中返回对象*/
            Object resultObject= userSession.get(key);
            if(resultObject!=null){
                /*刷新对应key值的指针,顺延session过期时间*/
                DelayElements delayElements=new DelayElements(key,_aliveTime);
                queue.remove(delayElements);
                queue.put(delayElements);
                System.out.println("获取"+key+"成功:"+resultObject+",生命周期重新计算");
            }else{
                System.out.println("获取"+key+"失败:"+resultObject+"。对象已过期");
            }
            return resultObject;
        }

        private void sessionGcMethod() throws InterruptedException{
            while(true){
                // 延迟时间内take方法不会获取到值
                // 那么将阻塞线程
                DelayElements delayElements = queue.take();
                queue.remove(delayElements);
                userSession.remove(delayElements.getKey());
                System.out.println("删除过期元素key"+delayElements.getKey());
                Thread.sleep(300);
            }
        }

        public void startSession(){
            Thread seesionGcThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        sessionGcMethod();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
            // 设置为守护线程
            seesionGcThread.setDaemon(true);
            seesionGcThread.start();
        }
    }

测试

package com.yvan.DelayQueue;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
 * 延时列队
 * @author yvan
 *
 */
public class SessionDelayQueue {

    public static void main(String[] args) throws InterruptedException {
        Session session = new Session();
        session.startSession();
        session.put("username", "yvan");
        Thread.sleep(4000);
        session.put("userlevel", "svip");
        session.get("username");
        Thread.sleep(1000);
        session.get("userlevel");
        Thread.sleep(1000);
        session.get("username");
        Thread.sleep(1000);
        session.get("userlevel");
        Thread.sleep(6000);
        session.get("username");
        Thread.sleep(3000);
        session.get("userlevel");
        Thread.sleep(7000);
        session.get("username");
    }
}

添加session key:username,value:yvan成功
添加session key:userlevel,value:svip成功
获取username成功:yvan,生命周期重新计算
获取userlevel成功:svip,生命周期重新计算
获取username成功:yvan,生命周期重新计算
获取userlevel成功:svip,生命周期重新计算
获取username成功:yvan,生命周期重新计算
删除过期元素keyuserlevel
获取userlevel失败:null。对象已过期
删除过期元素keyusername
获取username失败:null。对象已过期

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值