具有所述超时的Future对象在下一个线程中持续增加(超时不适用于Java线程池中的所有线程)

具有所述超时的Future对象在下一个线程中持续增加(超时不适用于Java线程池中的所有线程),java,timeout,java-7,future,executorservice,Java,Timeout,Java 7,Future,Executorservice,这里定义的工作线程在run方法中具有10秒的繁重任务 import java.util.Date; import java.util.Random; import java.util.concurrent.Callable; public class WorkerThread implements Callable { private String command; private long startTime; public WorkerThread(String s){ this

这里定义的工作线程在run方法中具有10秒的繁重任务

import java.util.Date;
import java.util.Random;
import java.util.concurrent.Callable;

public class WorkerThread implements Callable {

private String command;
private long startTime;
public WorkerThread(String s){
    this.command=s;
}

@Override
public Object call() throws Exception {
    startTime = System.currentTimeMillis();
    System.out.println(new Date()+"::::"+Thread.currentThread().getName()+" Start. Command = "+command);
    Random generator = new Random(); 
    Integer randomNumber = generator.nextInt(5); 
    processCommand();
    System.out.println(new Date()+ ":::"+Thread.currentThread().getName()+" End.::"+command+"::"+ (System.currentTimeMillis()-startTime));
    return randomNumber+"::"+this.command;
}

private void processCommand() {
    try {
        Thread.sleep(10000);
    } 
    catch (Exception e) {

        System.out.println("Interrupted::;Process Command:::"+this.command);
    }
}

@Override
public String toString(){
    return this.command;
}

}
定义了我的WorkerPool,未来获取超时为1秒

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class WorkerPool {

        static BlockingQueue queue=new LinkedBlockingQueue(2);
        static RejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl();
        static ThreadFactory threadFactory = Executors.defaultThreadFactory();
        static ThreadPoolExecutor executorPool = new ThreadPoolExecutor(4, 4, 11, TimeUnit.SECONDS, queue, threadFactory, rejectionHandler);
        static MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
        public static void main(String args[]) throws InterruptedException, TimeoutException{
            List<Future<Integer>> list = new ArrayList<Future<Integer>>();
            for(int i=1; i< 5; i++){
                WorkerThread worker = new WorkerThread("WorkerThread:::_"+i);
                Future<Integer> future = executorPool.submit(worker);
                list.add(future);
            }

            for(Future<Integer> future : list){
                try {
                    try {
                        future.get(1000, TimeUnit.MILLISECONDS);
                    } catch (TimeoutException e) {
                        future.cancel(true);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            executorPool.shutdown();
        }

    }
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.LinkedBlockingQueue;
导入java.util.concurrent.ThreadFactory;
导入java.util.concurrent.ThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.TimeoutException;
公共类WorkerPool{
静态阻塞队列=新的LinkedBlockingQueue(2);
静态RejectedExecutionHandlerImpl rejectionHandler=新的RejectedExecutionHandlerImpl();
静态ThreadFactory ThreadFactory=Executors.defaultThreadFactory();
静态ThreadPoolExecutor executorPool=新的ThreadPoolExecutor(4,4,11,TimeUnit.SECONDS,queue,threadFactory,rejectionHandler);
静态MyMonitorThread监视器=新的MyMonitorThread(executorPool,3);
公共静态void main(字符串args[])抛出InterruptedException、TimeoutException{
列表=新的ArrayList();
对于(int i=1;i<5;i++){
WorkerThread worker=新的WorkerThread(“WorkerThread::”+i);
Future=executorPool.submit(worker);
增加(未来);
}
用于(未来:列表){
试一试{
试一试{
get(1000,时间单位毫秒);
}捕获(超时异常e){
future.cancel(true);
}
}捕获(例外e){
e、 printStackTrace();
}
}
executorPool.shutdown();
}
}
对于未来的线程,线程的超时时间将持续增加,我的期望是,如果所有线程占用的时间超过1秒,那么应该一次关闭所有线程!第二

在aboce场景中,工作线程的处理时间为10秒,但我将在1秒内完成所有4个线程的计时,但每个任务的每个线程时间都会增加1秒

第一次超时为1秒 秒超时为2秒 第三次超时为3秒


为什么所有线程本身没有在1秒内中断?我的代码有问题吗?

因为您在本节的循环中按顺序等待:

for(Future<Integer> future : list) {
  ...
  future.get(1000, TimeUnit.MILLISECONDS);
  ...
}
如果您想为所有工作人员最多等待1秒,则需要计算到目前为止等待的时间,然后等待剩余的时间。 类似于伪代码:

long quota = 1000
for (Future future : futures) {
  long start = System.currentTimeMillis
  try {
    future.get(quota, MILLISECONDS)
  }
  catch (TimeoutException e) {
    future.cancel(true)
  }
  finally {
    long spent = System.currentTimeMillis() - start
    quota -= spent
    if (quota < 0) {quota = 0} // the whole block is going to execute longer than .get() only
  }
}


long配额=1000
for(未来:未来){
长启动=System.currentTimeMillis
试一试{
future.get(配额,毫秒)
}
捕获(超时异常e){
future.cancel(真)
}
最后{
长时间使用=System.currentTimeMillis()-开始
配额-=已用
如果(quota<0){quota=0}//整个块的执行时间将仅长于.get()
}
}

此解决方案仅适用于corepool大小,如果线程在队列中则不起作用为什么如此复杂?只需定义
long deadline=System.currentTimeMillis()+1000在循环之前。然后,只需
future.get(Math.max(0,deadline-System.currentTimeMillis()),毫秒)在循环中。或者,将所有可调用的
放入
列表中并调用,以免费获取逻辑。
long quota = 1000
for (Future future : futures) {
  long start = System.currentTimeMillis
  try {
    future.get(quota, MILLISECONDS)
  }
  catch (TimeoutException e) {
    future.cancel(true)
  }
  finally {
    long spent = System.currentTimeMillis() - start
    quota -= spent
    if (quota < 0) {quota = 0} // the whole block is going to execute longer than .get() only
  }
}