Java 为什么可以';我是否构造一个由延迟队列支持的ThreadPoolExecutor?
我正在尝试创建ThreadPoolExecutor:Java 为什么可以';我是否构造一个由延迟队列支持的ThreadPoolExecutor?,java,compiler-errors,executors,Java,Compiler Errors,Executors,我正在尝试创建ThreadPoolExecutor: // Thingy implements Delayed and Runnable ExecutorService executor = new ThreadPoolExecutor(1, 1, 0l, TimeUnit.SECONDS, new DelayQueue<Thingy>()); //Thingy实现延迟和可运行 ExecutorService executor=新的ThreadPoolExecutor(1,1,0l
// Thingy implements Delayed and Runnable
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0l, TimeUnit.SECONDS, new DelayQueue<Thingy>());
//Thingy实现延迟和可运行
ExecutorService executor=新的ThreadPoolExecutor(1,1,0l,TimeUnit.SECONDS,new DelayQueue());
编译器说“找不到符号”:
symbol:constructor ThreadPoolExecutor(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.DelayQueue)
但是我不明白-
DelayQueue
实现了BlockingQueue
,所以我不能使用吗?这是一个泛型问题。您不能使用DelayQueue
,它必须是DelayQueue
,因为ThreadPoolExecutor
构造函数未声明接受Runnable
子类型的队列RunnableScheduledFuture
是可运行和延迟的,但它不能强制转换为BlockingQueue
。看看为什么
看看
ScheduledThreadPoolExecutor
,它可以安排命令在给定延迟后运行,或者定期执行 虽然这是一个老问题,但我想发布我的答案,因为我最近正在寻找这个解决方案。可以在ThreadPoolExecutor后面使用DelayQueue,这只需要一些代码包装。诀窍是让DelayQueue以阻塞队列的形式出现
我首先定义了一个接口DR
,它扩展了Runnable
和Delayed
。注意,这里的静态方法创建DR的实例(未显示实例类)
实现应该覆盖:public int compareTo(延迟的o)
,public boolean equals(对象o)
,以及public int hashCode()
创建一个扩展DelayQueue的类。此类添加了一个方法,该方法将DelayQuue表示为BlockingQueue。返回的类只是包装DelayQueue,并在必要时使用DR
接口的make
方法将Runnable
转换为DR
public class DelayedBlockingQueue extends DelayQueue<DR> {
public BlockingQueue<Runnable> asRunnableQueue() {
return new BlockingQueue<Runnable>(){
DelayedBlockingQueue dbq = DelayedBlockingQueue.this;
public boolean add(Runnable e) {
return dbq.add( DR.make( e ));
}
private List<DR> makeList( Collection<? extends Runnable> coll)
{
return coll.stream().map( r -> DR.make( r ) ).collect( Collectors.toList() ) ;
}
public boolean addAll(Collection<? extends Runnable> arg0) {
return dbq.addAll(makeList( arg0 ) );
}
public void clear() {
dbq.clear();
}
public boolean contains(Object o) {
if (o instanceof Runnable) {
return dbq.contains( DR.make( (Runnable)o ) );
}
return false;
}
public boolean containsAll(Collection<?> arg0) {
List<DR> lst = new ArrayList<DR>();
for (Object o : arg0)
{
if (o instanceof Runnable)
{
lst.add( DR.make( (Runnable)o ) );
}
else {
return false;
}
}
return dbq.containsAll( lst );
}
public int drainTo(Collection<? super Runnable> c, int maxElements) {
return dbq.drainTo( c, maxElements );
}
public int drainTo(Collection<? super Runnable> c) {
return dbq.drainTo( c );
}
public Runnable element() {
return dbq.element();
}
public void forEach(Consumer<? super Runnable> arg0) {
dbq.forEach( arg0 );
}
public boolean isEmpty() {
return dbq.isEmpty();
}
public Iterator<Runnable> iterator() {
return WrappedIterator.create( dbq.iterator() ).mapWith( dr -> (Runnable)dr );
}
public boolean offer(Runnable e, long timeout, TimeUnit unit) throws InterruptedException {
return dbq.offer( DR.make( e ), timeout, unit );
}
public boolean offer(Runnable e) {
return dbq.offer( DR.make( e ) );
}
public Runnable peek() {
return dbq.peek();
}
public Runnable poll() {
return dbq.poll();
}
public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException {
return dbq.poll( timeout, unit );
}
public void put(Runnable e) throws InterruptedException {
dbq.put( DR.make(e) );
}
public int remainingCapacity() {
return dbq.remainingCapacity();
}
public Runnable remove() {
return dbq.remove();
}
public boolean remove(Object o) {
if (o instanceof Runnable)
{
return dbq.remove( DR.make( (Runnable)o) );
}
return false;
}
public boolean removeAll(Collection<?> arg0) {
List<DR> lst = new ArrayList<DR>();
for (Object o : arg0)
{
if (o instanceof Runnable)
{
lst.add( DR.make( (Runnable)o ) );
}
}
return dbq.removeAll( lst );
}
public boolean retainAll(Collection<?> arg0) {
return dbq.retainAll( arg0 );
}
public int size() {
return dbq.size();
}
public Runnable take() throws InterruptedException {
return dbq.take();
}
public Object[] toArray() {
return dbq.toArray();
}
public <T> T[] toArray(T[] arg0) {
return dbq.toArray( arg0 );
}
};
}
谢谢伙计,仿制药太疯狂了,我还需要帮助。我将其更改为
newdelayqueue()
,但这也不起作用,因为DelayQueue
被声明为DelayQueue
,因此显然我需要指定扩展Delayed
的内容,但我还需要指定Runnable
-这太疯狂了。请帮忙@很好,我没发现。我认为在这种情况下,你要么放弃DelayQueue
,要么使用未经检查的强制转换。如果ThreadPoolExecutor
已声明接受blockingqueue,请注意我尝试了此解决方案,但它不起作用。如果线程不忙,ThreadPoolExector将完全绕过队列。
public interface DR extends Delayed, Runnable {
public static DR make( Runnable r )
{
if (r instanceof DR)
{
return (DR)r;
}
Impl impl = new Impl(r);
if (r instanceof Delayed)
{
impl.expires = ((Delayed) r).getDelay( TimeUnit.MILLISECONDS );
}
return impl;
}
public static DR make( Runnable r, long expires )
{
if (r instanceof DR)
{
if (expires == ((DR)r).getDelay( TimeUnit.MILLISECONDS ))
{
return (DR)r;
}
}
return new Impl(r, expires);
}
}
public class DelayedBlockingQueue extends DelayQueue<DR> {
public BlockingQueue<Runnable> asRunnableQueue() {
return new BlockingQueue<Runnable>(){
DelayedBlockingQueue dbq = DelayedBlockingQueue.this;
public boolean add(Runnable e) {
return dbq.add( DR.make( e ));
}
private List<DR> makeList( Collection<? extends Runnable> coll)
{
return coll.stream().map( r -> DR.make( r ) ).collect( Collectors.toList() ) ;
}
public boolean addAll(Collection<? extends Runnable> arg0) {
return dbq.addAll(makeList( arg0 ) );
}
public void clear() {
dbq.clear();
}
public boolean contains(Object o) {
if (o instanceof Runnable) {
return dbq.contains( DR.make( (Runnable)o ) );
}
return false;
}
public boolean containsAll(Collection<?> arg0) {
List<DR> lst = new ArrayList<DR>();
for (Object o : arg0)
{
if (o instanceof Runnable)
{
lst.add( DR.make( (Runnable)o ) );
}
else {
return false;
}
}
return dbq.containsAll( lst );
}
public int drainTo(Collection<? super Runnable> c, int maxElements) {
return dbq.drainTo( c, maxElements );
}
public int drainTo(Collection<? super Runnable> c) {
return dbq.drainTo( c );
}
public Runnable element() {
return dbq.element();
}
public void forEach(Consumer<? super Runnable> arg0) {
dbq.forEach( arg0 );
}
public boolean isEmpty() {
return dbq.isEmpty();
}
public Iterator<Runnable> iterator() {
return WrappedIterator.create( dbq.iterator() ).mapWith( dr -> (Runnable)dr );
}
public boolean offer(Runnable e, long timeout, TimeUnit unit) throws InterruptedException {
return dbq.offer( DR.make( e ), timeout, unit );
}
public boolean offer(Runnable e) {
return dbq.offer( DR.make( e ) );
}
public Runnable peek() {
return dbq.peek();
}
public Runnable poll() {
return dbq.poll();
}
public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException {
return dbq.poll( timeout, unit );
}
public void put(Runnable e) throws InterruptedException {
dbq.put( DR.make(e) );
}
public int remainingCapacity() {
return dbq.remainingCapacity();
}
public Runnable remove() {
return dbq.remove();
}
public boolean remove(Object o) {
if (o instanceof Runnable)
{
return dbq.remove( DR.make( (Runnable)o) );
}
return false;
}
public boolean removeAll(Collection<?> arg0) {
List<DR> lst = new ArrayList<DR>();
for (Object o : arg0)
{
if (o instanceof Runnable)
{
lst.add( DR.make( (Runnable)o ) );
}
}
return dbq.removeAll( lst );
}
public boolean retainAll(Collection<?> arg0) {
return dbq.retainAll( arg0 );
}
public int size() {
return dbq.size();
}
public Runnable take() throws InterruptedException {
return dbq.take();
}
public Object[] toArray() {
return dbq.toArray();
}
public <T> T[] toArray(T[] arg0) {
return dbq.toArray( arg0 );
}
};
}
DelayedBlockingQueue queue = new DelayedBlockingQueue();
ThreadPoolExecutor execService = new ThreadPoolExecutor( 1, 5, 30, TimeUnit.SECONDS, queue.asRunnableQueue() );