How do i set up a DelayQueue's Delay

前端 未结 4 885
梦如初夏
梦如初夏 2021-01-19 04:42

I\'m just starting out coding in java i\'m in struggling with setting up a DelayQueue,

I wanted to have it so,

DelayQueue queue = new DelayQueue();

         


        
相关标签:
4条回答
  • 2021-01-19 04:50

    this implementation of Delayed is good because:

    • implementation of compareTo() does not do any class casting, eliminatig the possibility of throwing a ClassCastException
    • implementation of compareTo() uses Math.min and Math.max functions before casting to int in order to properly prevent overflow errors
    • implementation of getDelay() properly converts the units and actually returns the time remaining

    TestDelay class implements Delayed:

    import org.jetbrains.annotations.NotNull;
    
    import java.util.concurrent.Delayed;
    import java.util.concurrent.TimeUnit;
    
    public class TestDelay implements Delayed
    {
        public final Long delayMillis;
        public final Long expireTimeMillis;
    
        public TestDelay(Long delayMillis)
        {
            this.delayMillis = delayMillis;
            this.expireTimeMillis = System.currentTimeMillis()+delayMillis;
        }
    
        @Override
        public final int compareTo(@NotNull Delayed o)
        {
            long diffMillis = getDelay(TimeUnit.MILLISECONDS)-o.getDelay(TimeUnit.MILLISECONDS);
            diffMillis = Math.min(diffMillis,1);
            diffMillis = Math.max(diffMillis,-1);
            return (int) diffMillis;
        }
    
        @Override
        public final long getDelay(@NotNull TimeUnit unit)
        {
            long delayMillis = expireTimeMillis-System.currentTimeMillis();
            return unit.convert(delayMillis,TimeUnit.MILLISECONDS);
        }
    }
    

    JUnit unit test showing an example of using the TestDelay class:

    import org.junit.Test;
    
    import java.util.concurrent.DelayQueue;
    
    public class DelayQueueTest
    {
        @Test
        public final void generalTest() throws InterruptedException
        {
            DelayQueue<TestDelay> q = new DelayQueue<>();
            q.put(new TestDelay(500L));
            q.put(new TestDelay(2000L));
            q.put(new TestDelay(1000L));
            q.put(new TestDelay(10L));
            q.put(new TestDelay(3000L));
            while (!q.isEmpty())
            {
                System.out.println(q.take().delayMillis);
            }
        }
    }
    

    output of DelayQueueTest:

    0 讨论(0)
  • 2021-01-19 04:50
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.DelayQueue;
    import java.util.concurrent.Delayed;
    import java.util.concurrent.TimeUnit;
    
    public class DelayQueueExample {
    
        public static void main(String[] args) {
    
            BlockingQueue<DelayedElement> blockingQueue = new DelayQueue<DelayedElement>();
    
            try {
                blockingQueue
                        .put(new DelayedElement(4000, "Message with delay 4s"));
                blockingQueue
                        .put(new DelayedElement(2000, "Message with delay 2s"));
                blockingQueue
                        .put(new DelayedElement(9000, "Message with delay 9s"));
            } catch (InterruptedException ie) {
            }
    
            while (!blockingQueue.isEmpty()) {
                try {
                    System.out.println(">>" + blockingQueue.take());
                } catch (InterruptedException ie) {
                }
    
            }
    
        }
    }
    
    class DelayedElement implements Delayed {
    
        private long duration = 0;
        private String message;
    
        public DelayedElement(long duration, String name) {
            this.duration = System.currentTimeMillis() + duration;
            this.message = name;
        }
    
        @Override
        public int compareTo(Delayed o) {
            return (int) (this.duration - ((DelayedElement) o).getDuration());
        }
    
        @Override
        /*
         * Expiration occurs when an element's getDelay(TimeUnit unit) method
         * returns a value less than or equal to zero.
         */
        public long getDelay(TimeUnit unit) {
            long diff = duration - System.currentTimeMillis();
            return unit.convert(diff, TimeUnit.MILLISECONDS);
        }
    
        public long getDuration() {
            return duration;
        }
    
        public void setDuration(long duration) {
            this.duration = duration;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        @Override
        public String toString() {
            return "DelayedElement [duration=" + duration + ", message=" + message
                    + "]";
        }
    
    }
    
    0 讨论(0)
  • 2021-01-19 04:56

    Your "custom delay" classes must return the delay from the getDelay(TimeUnit timeUnit) method specified in the Delayed interface. E.g.

    public class MyClass implements Delayed {
        public long getDelay(TimeUnit timeUnit) {
            long delay = calculateDelaySomehow();
            return delay;
        }
    }
    

    Note that you also need to provide an implementation for compareTo().

    0 讨论(0)
  • 2021-01-19 05:07

    The DelayQueue keeps the elements internally until a certain delay has expired. The elements must implement the interface java.util.concurrent.Delayed.

    For example I have created a class DelayedTest extending Delayed interface. This will implement compareTo and getDelay() method

    public class A{
        public static void main(String... args){
            DelayQueue  dq=new DelayQueue();
            DeleyedTest ob1=new DeleyedTest(10);
            DeleyedTest ob2=new DeleyedTest(5);
            DeleyedTest ob3=new DeleyedTest(15);
    
            dq.offer(ob1);
            dq.offer(ob2);
            dq.offer(ob3);
    
            Iterator itr=dq.iterator();
            while(itr.hasNext()){
                DeleyedTest dt=(DeleyedTest)itr.next();
                System.out.println(dt.deleyTime);
            }
        }
    }
    class DeleyedTest implements Delayed{
        public long deleyTime=0;
        DeleyedTest(long deleyTime){
            this.deleyTime=deleyTime;
        }
    
        @Override
        public int compareTo(Delayed ob) {
            if(this.deleyTime<((DeleyedTest)ob).deleyTime){
                return -1;
            }else if(this.deleyTime>((DeleyedTest)ob).deleyTime){
                return 1;
            }
            return 0;
        }
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(deleyTime-System.currentTimeMillis(),TimeUnit.NANOSECONDS); 
        }
    
    }
    

    Result:

    5
    10
    15
    0 讨论(0)
提交回复
热议问题