线程从执行器服务请求新任务

时间:2015-01-13 19:21:24

标签: java multithreading threadpool executorservice threadpoolexecutor

我目前有收集任务的主要方法。收集任务后,将使用固定的线程池大小调用ExecutorService。迭代任务并将其提交给执行者。

但是我需要刷新任务,如果有任何新任务可用,我会将它添加到执行程序中。但是如果其中一个线程是空闲的而没有从队列中分配任何任务,我希望该线程手动通知我的主线程刷新事件并提交给执行程序,甚至在我的手动刷新发生之前。我怎样才能做到这一点。感谢

示例代码

public class Sample{
   Map<String, List<Integer>> tasks;
   ThreadPoolExecutor executor;

   public static void main(String[] args) {
     executor = Executors.newFixedThreadPool(2);
     tasks = Collections.synchronizedMap(new HashMap<String, List<Integer>>());
     tasks =  Tasks.refresh(); //This will get me a new set of data to be processed
     invokeexecutor();
   }
   public void invokeexecutor(){
      for(String key: tasks.keyset())
      {
       executor.submit(new TaskRunnable(tasks.get(key));
      }
      tasks.clear(); //Remove the allocated tasks from the collection
   }
}

public class TaskRunnable implements Runnable{
   public void run(){
        //Do some logic
   }
}

在这种情况下,我希望我的任务中的数据能够在10秒后持续刷新,或者如果任何执行程序线程都是空闲的,则必须进行此刷新,并且新的可运行程序将被分配给该线程。

2 个答案:

答案 0 :(得分:2)

  

但是如果其中一个线程是空闲的而没有从队列中分配任何任务,我希望该线程手动通知我的主线程刷新事件并提交给执行程序,甚至在我的结束手动刷新之前。我怎样才能做到这一点。

有几种方法可以轻松实现这一目标。一种方法是自己创建`ThreadPoolExecutor'。

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
                                             new LinkedBlockingQueue<Runnable>());

然后有一个轮询线程监视ThreadPoolExecutor类以确定是否有任何空闲线程。类似的东西:

 while (!Thread.currentThread().isInterrupted()) {
     // sleep a bit
     Thread.sleep(1000);
     if (executor.getActiveCount() < 2) {
        // add tasks here
     }
 }

然而,轮询线程有点粗糙。另一个更简单的想法是使用固定大小的任务队列,然后总是尝试将任务添加到列表中。如果队列已满,这将阻止。类似的东西:

// create a limited blocking queue
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
                                             new LinkedBlockingQueue<Runnable>(10));
 while (!Thread.currentThread().isInterrupted()) {
     // add tasks here which will block if too many in the queue
 }

答案 1 :(得分:1)

您可以尝试在ThreadPoolExecutor中覆盖afterExecute方法。当池中的线程执行任务时调用它。

class MyThreadPoolExecutor extends ThreadPoolExecutor {
    public MyThreadPoolExecutor {
        super(/*Call one of TheadPoolExecutor constructors*/)
    }

    protected afterExecute(Runnable r, Throwable t) {
        // Notify main thread here
    }
}