Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的DelayQueue-未按预期工作_Java_Java.util.concurrent - Fatal编程技术网

java中的DelayQueue-未按预期工作

java中的DelayQueue-未按预期工作,java,java.util.concurrent,Java,Java.util.concurrent,我是并发编程新手。我创建了两个类DelayedElement.java和DelayQueueExample来理解DelayQueue,如下所示: import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; public class DelayQueueExample { public static void main(String[] args) throws InterruptedExcep

我是并发编程新手。我创建了两个类DelayedElement.java和DelayQueueExample来理解DelayQueue,如下所示:

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;

public class DelayQueueExample {
    public static void main(String[] args) throws InterruptedException {
        DelayQueue queue = new DelayQueue();
        Delayed element1 = new DelayedElement(5);
        queue.put(element1);
        System.out.println("Put done");
        Delayed element2 = queue.take();
        System.out.println("Take done");
        System.out.println(((DelayedElement)element2).getI());
    }
}
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayedElement implements Delayed {

    private int i;
    public DelayedElement(int i) {
        this.setI(i);
    }

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

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = 10000l;
        return  unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

}
DelayedElement类如下所示:

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;

public class DelayQueueExample {
    public static void main(String[] args) throws InterruptedException {
        DelayQueue queue = new DelayQueue();
        Delayed element1 = new DelayedElement(5);
        queue.put(element1);
        System.out.println("Put done");
        Delayed element2 = queue.take();
        System.out.println("Take done");
        System.out.println(((DelayedElement)element2).getI());
    }
}
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayedElement implements Delayed {

    private int i;
    public DelayedElement(int i) {
        this.setI(i);
    }

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

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = 10000l;
        return  unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

}
我运行了程序,输出结果显示put已完成。但当我调用
queue.take()
操作时,它会无限延迟。我在DelayedElement的getDeley方法中将延迟时间指定为10秒。那么为什么我的程序是这样运行的呢?有人能帮我理解我错在哪里吗?

试着用下面的方式实现getDelay()。origin是将项目放入队列的时间(毫秒)

@Override
    public long getDelay( TimeUnit unit ) {
        return unit.convert( delay - ( System.currentTimeMillis() - origin ),
                TimeUnit.MILLISECONDS );
    }
尝试以下面的方式实现getDelay()。origin是将项目放入队列的时间(毫秒)

@Override
    public long getDelay( TimeUnit unit ) {
        return unit.convert( delay - ( System.currentTimeMillis() - origin ),
                TimeUnit.MILLISECONDS );
    }

如DelayedQueue的java文档中所述

元素的getDelay(时间单位纳秒)过期时发生 方法返回小于或等于零的值

您已经重写了getDelay(TimeUnit.NANOSECONDS)方法,因此它总是返回一个常量延迟。你应该改变它,使延迟随着时间的推移而减少

差不多

// startTime is some future time set while creating delay element.
public long getDelay(TimeUnit unit) {
        long diff = startTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
}

如DelayedQueue的java文档中所述

元素的getDelay(时间单位纳秒)过期时发生 方法返回小于或等于零的值

您已经重写了getDelay(TimeUnit.NANOSECONDS)方法,因此它总是返回一个常量延迟。你应该改变它,使延迟随着时间的推移而减少

差不多

// startTime is some future time set while creating delay element.
public long getDelay(TimeUnit unit) {
        long diff = startTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
}

根据延迟接口的javadoc,getDelay(TimeUnit TimeUnit)应该返回从元素添加到队列的时间算起的剩余延迟时间

一种简单的方法是,在将元素添加到队列时设置过期时间(基于current time&dealy参数),并在调用getDelay方法时返回过期时间中的剩余时间

实现可以是这样的

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayedElement implements Delayed {
    private int i;
    /*
     * Expiry time in nano-seconds(more granular) 
     * i.e. time in nano seconds at which the element is added + delay converted to nanoseconds
     */
    private long expiryTime; 

    public DelayedElement(int i, int delay, TimeUnit dealyTimeUnit) {
        this.setI(i);
        expiryTime = TimeUnit.NANOSECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS) + TimeUnit.NANOSECONDS.convert(delay, dealyTimeUnit);
    }

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

    @Override
    public long getDelay(TimeUnit unit) {
           return  unit.convert((expiryTime- TimeUnit.NANOSECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS)), TimeUnit.NANOSECONDS);
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }
}

根据延迟接口的javadoc,getDelay(TimeUnit TimeUnit)应该返回从元素添加到队列的时间算起的剩余延迟时间

一种简单的方法是,在将元素添加到队列时设置过期时间(基于current time&dealy参数),并在调用getDelay方法时返回过期时间中的剩余时间

实现可以是这样的

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayedElement implements Delayed {
    private int i;
    /*
     * Expiry time in nano-seconds(more granular) 
     * i.e. time in nano seconds at which the element is added + delay converted to nanoseconds
     */
    private long expiryTime; 

    public DelayedElement(int i, int delay, TimeUnit dealyTimeUnit) {
        this.setI(i);
        expiryTime = TimeUnit.NANOSECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS) + TimeUnit.NANOSECONDS.convert(delay, dealyTimeUnit);
    }

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

    @Override
    public long getDelay(TimeUnit unit) {
           return  unit.convert((expiryTime- TimeUnit.NANOSECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS)), TimeUnit.NANOSECONDS);
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }
}

为什么需要这个?为什么需要这个?我没有传递任何小于等于零的值。我正在传递正值10000毫秒。DelayedQueue只返回其getDelay()方法返回负值或零的元素。如果它没有找到任何这样的元素,它就会开始周期性地等待,直到某个元素满足这个条件。在你的例子中,你总是返回一个常数时间,所以没有一个元素满足这个条件,它一直在无限期地等待。我不会传递任何小于等于零的值。我正在传递正值10000毫秒。DelayedQueue只返回其getDelay()方法返回负值或零的元素。如果它没有找到任何这样的元素,它就会开始周期性地等待,直到某个元素满足这个条件。在你的例子中,你总是返回一个恒定的时间,所以没有一个元素满足这个条件,它会无限期地等待。