0 0

使用ThreadPoolExecutor并没有得到应有的性能提升,请各位帮忙看一下原因.3

要使用线程池往服务器发送多个请求,得到响应后再对响应进行合并.以下是伪代码实现:

Request[] requests = getRequests();
ThreadPoolExecutor pool = new ThreadPoolExecutor(200, 200, 10, queue);
Future[] futures = new Future[requests.length];

//a.使用线程池发送请求
for (int i = 0; i < requests.length; i++)
{
     final Request request  requests[i];
     future[i] = pool.submit(new Callable<Response>(){
          public Response call()
          {
              return getResponse();
          }
     });
}

//b.处理得到的响应
Response[] responses = new Response[requests.length];
for (int i =0; i < futures.length; i++)
{
    if (!futures[i].isCancelled())
    {
        if (futures[i].isDone())
        {
            responses[i] = futures[i].get();
        }
        while(!futures[i].isDone())
        {
            try
            {
                responses[i] = futures[i].get();
            }
            catch (InturreptException e)
            {
                //
            }
        }
    }
}

//c.返回响应
return responses;



测试后发现,上述a部分使用线程池发送请求速度很快,但是在b部分处理响应是性能不高.这一块在等待响应的返回,必须等所有的响应都回来之后才返回.
不知各位有没有遇到这样的问题,应该如何解决,谢谢.

问题补充:
fmjsjx 写道
典型生产者与消费者模型……
结果不要放在数组里,可以用队列处理
a的结果直接添加到队列里
b处理就从队列里拿


队列是application级的公用队列吗?不过即便使用队列也起不了作用吧?我要实现的逻辑是发送多个请求过去,然后得到所有响应,最后对所有的响应进行合并,再返回给用户.这样必须等所有的响应都返回以后才能对响应进行处理,使用队列又能起到什么作用呢?

问题补充:应用场景是这样的:要实现查询商品的价格,服务器每次请求只能查询100个商品的价格,我们首先将请求按100个一组将请求分拆成多个请求,然后通过线程池发送到服务器,然后得到所有的响应,再将所有的响应合并成一个,返回给用户.这就要求所有的响应都回来后才能进行处理,这样就有一个等待的过程.请考虑.

问题补充:
fmjsjx 写道
Future是个异步计算的结果,这个结果在什么时间返回是不确定的,而Future本身并没有一个主动上报的机制,导致必须通过线程轮询来判断结果十分返回,这个效率的确比较差。
提高效率就尽量不要使用Future,线程池也提供了其他的方式返回线程结果,线程的执行过程可以是把线程执行的结果放入一个List,在判断List的size()是不是和请求数相符,相符就表示结果都返回了,就返回给用户,没有就什么都不做,等待下一个线程再作判断。

能具体说一下有哪种还可以返回线程结果?
2011年6月04日 07:52

5个答案 按时间排序 按投票排序

0 0

引用
Future是个异步计算的结果,这个结果在什么时间返回是不确定的,而Future本身并没有一个主动上报的机制,导致必须通过线程轮询来判断结果十分返回,这个效率的确比较差。


Future的get方法在返回和异常前会一直阻塞,所以应该不存在轮询问题。Future的效率很差吗?有没有什么相关资料?多谢

for (int i =0; i < futures.length; i++)  
{  
    if (!futures[i].isCancelled())  
    {  
        if (futures[i].isDone())  
        {  
            responses[i] = futures[i].get();  
        }  
        while(!futures[i].isDone())  
        {  
            try  
            {  
                responses[i] = futures[i].get();  
            }  
            catch (InturreptException e)  
            {  
                //  
            }  
        }  
    }  
}  

这段代码中判断isDone,还有while等等是否有意义?本身get方法是会阻塞的。但个人觉得性能问题不在这里,而在具体的处理线程。

2011年6月07日 16:37
0 0

引用
能具体说一下有哪种还可以返回线程结果?

可以直接用java.util.concurrent.Executor接口的public void execute(Runnable runnable)方法,虽然没有返回值,但可以在Runnable内部实现类里取出数据,只要结果集的声明是final就行了。

2011年6月07日 16:04
0 0

Future是个异步计算的结果,这个结果在什么时间返回是不确定的,而Future本身并没有一个主动上报的机制,导致必须通过线程轮询来判断结果十分返回,这个效率的确比较差。
提高效率就尽量不要使用Future,线程池也提供了其他的方式返回线程结果,线程的执行过程可以是把线程执行的结果放入一个List,在判断List的size()是不是和请求数相符,相符就表示结果都返回了,就返回给用户,没有就什么都不做,等待下一个线程再作判断。

2011年6月05日 11:21
0 0

你的需求是“这就要求所有的响应都回来后才能进行处理,这样就有一个等待的过程”,
怎么可以不等待呢?
没看出来这个和多线程有什么关系。

2011年6月04日 17:00
0 0

典型生产者与消费者模型……
结果不要放在数组里,可以用队列处理
a的结果直接添加到队列里
b处理就从队列里拿

2011年6月04日 14:57

相关推荐

Global site tag (gtag.js) - Google Analytics