java中的DelayQueue-未按预期工作
我是并发编程新手。我创建了两个类DelayedElement.java和DelayQueueExample来理解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
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()方法返回负值或零的元素。如果它没有找到任何这样的元素,它就会开始周期性地等待,直到某个元素满足这个条件。在你的例子中,你总是返回一个恒定的时间,所以没有一个元素满足这个条件,它会无限期地等待。