Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.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 如何构建受限制的Executor服务_Java_Multithreading_Executorservice - Fatal编程技术网

Java 如何构建受限制的Executor服务

Java 如何构建受限制的Executor服务,java,multithreading,executorservice,Java,Multithreading,Executorservice,我的问题是: 我在收到事件后执行了一个长时间运行的计算(我们称之为“任务”) 这些事件告诉我有更多的数据需要处理。该事件包括一个索引,说明我现在可以在何处安全地处理任务的数据 当我得到一个新事件时,我有更多的数据需要最终处理 当我得到一个新事件时,我不想取消现有任务,而是让它完成,然后开始下一个任务 如果我在一个任务中得到几个事件,那么下一个任务应该只处理最近的事件,并放弃所有以前的事件 我一次只能处理一项任务 是否有可用于实现上述条件的Executors.newSingleThreadExec

我的问题是:

  • 我在收到事件后执行了一个长时间运行的计算(我们称之为“任务”)
  • 这些事件告诉我有更多的数据需要处理。该事件包括一个索引,说明我现在可以在何处安全地处理任务的数据
  • 当我得到一个新事件时,我有更多的数据需要最终处理
  • 当我得到一个新事件时,我不想取消现有任务,而是让它完成,然后开始下一个任务
  • 如果我在一个任务中得到几个事件,那么下一个任务应该只处理最近的事件,并放弃所有以前的事件
  • 我一次只能处理一项任务

  • 是否有可用于实现上述条件的
    Executors.newSingleThreadExecutor()的修改版本?我可以用BlockingQueue或AtomicReferences做一些优雅的事情吗?有没有一种简单的方法可以完成我上面描述的任务?

    尝试使用Java ScheduledThreadPoolExecutor,它是ThreadPoolExecutor的扩展。您可以将线程池大小限制为1,以确保仅从队列中拾取一个任务。唯一的问题是ScheduledThreadPoolExecutor在内部使用DelayQueue的实现,DelayQueue是一个无界队列,但您只希望拾取最后一个任务/事件


    您可能必须扩展ScheduledThreadPoolExecutor类并使用与绑定到当前ScheduledThreadPoolExecutor实现的DelayedWorkQueue不同的队列。请注意,DelayedWorkQueue只是在幕后使用DelayQueue的BlockingQueue实现。覆盖所有schedule*方法并实现您自己的任务边界。

    您可能希望扩展到extend ThreadPoolExecutor以实现所需的结果,例如

    new ThreadPoolExecutor(min, max, keepAliveTime,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()) {
    
          @Override
          protected void beforeExecute(Thread t, Runnable r) {
            while (isThrottle()) {
              try {
                TimeUnit.MILLISECONDS.sleep(timeout);
              } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
              }
            }
          }
    
          private double isThrottle() {
            // TODO: 
          }
        };
    
    新线程池执行器(最小值、最大值、keepAliveTime、,
    TimeUnit.millizes,新的LinkedBlockingQueue(){
    @凌驾
    执行前受保护的void(线程t,可运行r){
    while(isThrottle()){
    试一试{
    时间单位。毫秒。睡眠(超时);
    }捕捉(中断异常e){
    Thread.currentThread().interrupt();
    打破
    }
    }
    }
    私人双伊斯特罗特尔(){
    //待办事项:
    }
    };
    
    因此,我不明白这与一个简单的生产者/消费者问题有什么不同,其中只有一个消费者,生产者将事件放入一个只适合一个元素的队列中。我在你的问题中遗漏了什么吗?你几乎是对的。主要问题在于对队列上的一个元素的访问。它必须是最新的元素,而不是最早的元素。所以你几乎可以认为它是一个元素堆栈。您知道Java中有一种解决方案可以以简单、优雅的方式实现这一点吗?