条件延迟处理

时间:2015-06-15 16:47:33

标签: java multithreading caching data-structures threadpool

我在glassfish下创建了一个新的线程池和一个新的关联监听器。线程池的最大容量为100个线程。我有一个每晚运行的预定作业,它应该从远程客户端触发HTTP GET请求。请注意,预定作业是 HTTP客户端。但是它会触发远程HTTP客户端发出HTTP GET请求。请求的数量可以超过100.即使请求数超过100,预定作业也应以不间断的方式运行。以下是伪代码

class ScheduledJob{

    public executeJob(){
    {
        for(i=0; i<=numberOfTasks; i++)
        {
            connectToTheClientsAndAskThemToFireHTTPGetRequests();
        }
    }

}

我想设计解决方案的方法是使 executeJob 方法以非阻塞方式执行。这意味着最初会触发100个请求,其余请求将被缓存。收到200 OK后,我会限制其余的请求。请注意,HTTP请求可能需要几秒钟,因为响应HTTP GET是一个20MB的二进制文件。这里的问题是有没有开箱即用的解决方案(数据结构)来执行我的缓存和触发业务逻辑,或者任何人都可以提出更好的解决方案。

1 个答案:

答案 0 :(得分:1)

一个选项是创建一个Runnable,它采用GetTasks的并发队列(或任何你想要命名的HTTP GET请求数据的包装器)。 executeJob()使用所有GetTasks填充队列,构造一个包含100个线程的线程池,并提交共享同一并发队列的100 RunnablesRunnables将轮询队列,直到它为空,此时它们终止。

public class GetTask {}

public class GetTaskExecutor implements Runnable {
   private final ConcurrentLinkedQueue<GetTask> queue;

   public GetTaskExecutor(ConcurrentLinkedQueue<GetTask> queue) {
     this.queue = queue;
   }

   public void run() {
     GetTask task = null;
     while((task = queue.poll()) != null) {
       // do work
     }
   }
}

class ScheduledJob{
    public boolean executeJob(){
        ExecutorService service = Executors.newFixedThreadPool(100);
        ConcurrentLinkedQueue<GetTask> queue = new ConcurrentLinkedQueue<>();
        for(i=0; i<=numberOfTasks; i++) {
            queue.offer(new GetTask());
        }
        for(int i = 0; i < 100; i++) {
            service.execute(new GetTaskExecutor(queue));
        }
        return service.awaitTermination(4, TimeUnit.HOURS);
    }
}

另一种方法是每GetTaskExecutor创建一个GetTask并将其全部提交给ExecutorService - 您正在使用固定的线程池,因此一次最多可执行100个任务

public class GetTaskExecutor implements Runnable {
   private final GetTask task;

   public GetTaskExecutor(GetTask task) {
     this.task = task;
   }

   public void run() {
     // do work on single task
   }
}

class ScheduledJob{
    public boolean executeJob(){
        ExecutorService service = Executors.newFixedThreadPool(100);
        for(i=0; i<=numberOfTasks; i++) {
            service.execute(new GetTaskExecutor(new GetTask());
        }
        return service.awaitTermination(4, TimeUnit.HOURS);
    }
}