根据时间限制运行线程

时间:2014-09-18 15:27:12

标签: java multithreading scheduled-tasks threadpool

我想每秒启动最多40个http请求,1秒后,我希望它从自己的队列中运行另外40个(如threadpooltaskexecutor的阻塞队列)。我正在为此要求寻找执行程序或线程池实现。

有什么建议吗?

THX

阿里

编辑:由于显而易见的原因,修复率效率不高。当队列项逐个开始时,队列背面的那些项将刚刚启动,但已启动一段时间的队列项可能已完成。

额外编辑:问题是一秒钟内只调用40个请求,而不是最多40个活动。它可以是80秒,但在1秒内,应该只有40个新创建的连接。

2 个答案:

答案 0 :(得分:0)

这样做的一种方法是使用另一种架构,它将使这个过程变得更加容易。

1)创建一个实现runnable的Thread类。 2)它作为参数获取您想要进行的http请求的列表<>() 3)使run()函数循环整个列表(大小40) 4)让线程活一秒钟。

以下是一个示例示例:

class MyClass extends Thread

private ArrayList<...> theList;

public MyClass(ArrayList<..> theList){
    this.theList = theList;
}

public void run(){
    //Here, you simply want to loop for the entier list (max 40)
    for(Req r: theList){
        r.sendRequest()
    )
}

public statc void main(String args[]){
  //Create an instance of your thread:
  MyClass t = new MyClass(ReqList<..>());

  //Now that you have your thread, simply do the following:

  while(true){
     t = new MyClass( (insert your new list));
     t.start();
     try{
       Thread.sleep(1000);
     }catch(Exception e){

     }
  )



}
}

你有它吗

答案 1 :(得分:0)

首先定义一个实现Callable的类,它将执行你的线程处理:

class MyClass implements Callable<String>
{
    /**
     * Consider this as a new Thread.
    */
    @Override
    public String call()
    {
        //Treatment...

        return "OK"; //Return whatever the thread's result you want to be then you can access it and do the desired treatment.
    }
}

下一步是在我的示例中创建一个ExecutorService,一个线程池并抛出一些任务。

int nbThreadToStart = 40;

ExecutorService executor = Executors.newFixedThreadPool(/* Your thread pool limit */);

List<Future<String>> allTasks = new ArrayList<Future<String>>(/* Specify a number here if you want to limit your thread pool */);

for(int i = 0; i < 10; i++)//Number of iteration you want
{
    for(int i = 0; i < nbThreadToStart; i++)
    {
        try
        {
            allTasks.add(executor.submit(new MyClass()));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    try
    {
        Thread.sleep(1000);
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
}

executor.shutdown();

//You can then access all your thread(Tasks) and see if they terminated and even add a timeout :

try
{
    for(Future<String> task : allTasks)
        task.get(60, TimeUnit.SECONDS);//Timeout of 1 seconds. The get will return what you specified in the call method.
}
catch (TimeOutException te)
{
    ...
}
catch(InterruptedException ie)
{
    ...
}
catch(ExecutionException ee)
{
    ...
}

我不确定你真正想要什么,但我认为如果你计划接收大量请求以避免任何意外的内存泄漏等,你应该使用线程池来处理多线程。

如果我的示例不够清楚,请注意ExexutorService,Future等提供的许多其他方法在处理Thread时非常有用。

检查出来:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html

这是我的建议。