Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 7并行执行并没有使用倒计时锁存器提高REST API的性能_Java_Multithreading_Rest_Parallel Processing_Countdownlatch - Fatal编程技术网

Java 7并行执行并没有使用倒计时锁存器提高REST API的性能

Java 7并行执行并没有使用倒计时锁存器提高REST API的性能,java,multithreading,rest,parallel-processing,countdownlatch,Java,Multithreading,Rest,Parallel Processing,Countdownlatch,我正在用Java7编写一个RESTAPI,从数据库中检索三个项目,并将这三个项目作为响应一起发送给用户。当程序在顺序流中运行时,即,如果我先获取一个项目,然后获取另一个项目,则执行该项目需要合理的时间。但是,当我使用多线程时,即使用三个线程从数据库中获取三个项目,与顺序执行相比,执行需要更多的时间。此问题导致CPU使用率高达90%以上。 例如: Sequential: number of users 60 average execution time-

我正在用Java7编写一个RESTAPI,从数据库中检索三个项目,并将这三个项目作为响应一起发送给用户。当程序在顺序流中运行时,即,如果我先获取一个项目,然后获取另一个项目,则执行该项目需要合理的时间。但是,当我使用多线程时,即使用三个线程从数据库中获取三个项目,与顺序执行相比,执行需要更多的时间。此问题导致CPU使用率高达90%以上。

例如:

     Sequential: number of users 60
                 average execution time- 5149 milliseconds

     Parallel:   number of users 60
                 average execution time- 9544 milliseconds
我使用ExecutorService来实现异步执行机制,并使用倒计时锁存器来同步线程

为什么并行执行比顺序执行花费更多的时间?这里使用倒计时闩锁有什么缺点吗

使用倒计时锁存器执行辅助线程的代码:

List<Runnable> workers;

if (StringUtils.isBlank(typeCode)) {
    workers =          
    ItemManagerHelper.determineItemLookupWorkersByItemIdentifiers(Id, ids,
    effectiveStartDate, effectiveEndDate, errors, ItemUIList, dataMap);
    }
else {
     workers = ItemManagerHelper.determineItemLookupWorkersByItemType(Id, 
     ids,effectiveStartDate,effectiveEndDate, typeCode, errors, ItemUIList, 
     dataMap);
    }

ExecutorService threadPoolExecutor = Executors.newFixedThreadPool                                            
(workers.size());

CountDownLatch latch = new CountDownLatch(workers.size());

for (Runnable worker : workers) {
      ((ItemLookupThread) worker).setLatch(latch);
      threadPoolExecutor.submit(worker);
}

try {
      latch.await(threadTimeOut, TimeUnit.MILLISECONDS);
} 
catch (InterruptedException e) {
      error(this.getClass(), e, "Exception occurred while waiting for the 
           lookup child threads completion.");
} 
finally {
      threadPoolExecutor.shutdown();
}
列出工人名单;
if(StringUtils.isBlank(类型代码)){
工人=
ItemManagerHelper.通过ItemIdentifiers(Id、Id、,
有效开始日期、有效结束日期、错误、项目列表、数据映射);
}
否则{
workers=ItemManagerHelper.DeterminiteItemLookupWorkers ByItemType(Id,
ID、有效开始日期、有效结束日期、类型代码、错误、ItemUIList、,
数据地图);
}
ExecutorService threadPoolExecutor=Executors.newFixedThreadPool
(workers.size());
CountDownLatch latch=新的CountDownLatch(workers.size());
for(可运行工作程序:工作程序){
((ItemLookupThread)worker);
threadPoolExecutor.submit(worker);
}
试一试{
等待(线程超时,时间单位为毫秒);
} 
捕捉(中断异常e){
错误(this.getClass(),e,“在等待
查找子线程完成。“);
} 
最后{
threadPoolExecutor.shutdown();
}
ItemLookupThread是我的线程类:

public class ItemLookupThread implements Runnable {

private ItemProvider provider;
private long Id;
ItemsIdentifiers ids;
private long effectiveStartDate;
private long effectiveEndDate;
private Map<Object, Object> dataMap;
private List<BaseResponse.Error> errors;
private List<ItemUI> Items;
private CountDownLatch latch;

  public ItemLookupThread (ItemProvider provider, long Id, 
    ItemsIdentifiers ids,long effectiveStartDate,
    long effectiveEndDate, Map<Object, Object> dataMap,      
    List<ItemUI> Items, List<BaseResponse.Error> errors) {

      this.provider = provider;
      this.Id = Id;
      this.ids = ids;
      this.effectiveStartDate = effectiveStartDate;
      this.effectiveEndDate = effectiveEndDate;
      this.dataMap = dataMap;
      this.Items = Items;
      this.errors = errors;
    }

 @Override
 public void run() {
    try {
       debug(this.getClass(), "Item lookup started :" + 
       Thread.currentThread().getId());
       provider.lookup(Id, ids, effectiveStartDate, effectiveEndDate, 
       dataMap, Items, errors);
       debug(this.getClass(), "Item lookup completed :" + 
       Thread.currentThread().getId());
    }

    finally {
         if (latch != null) {
         latch.countDown();
         }
    }
  }

  public void setLatch(CountDownLatch latch) {
          this.latch = latch;
  }
}
公共类ItemLookupThread实现可运行{
私人物品提供者;
私人长Id;
项目标识符ID;
私人长期有效起始日期;
私人长期有效终止日期;
私有地图数据地图;
私有列表错误;
私人清单项目;
私人倒计时闩锁;
公共ItemLookupThread(ItemProvider提供程序,长Id,
ItemSidentiers ID,长有效起始日期,
long effectiveEndDate,映射数据映射,
列出项目,列出错误){
this.provider=提供者;
这个.Id=Id;
this.ids=ids;
this.effectiveStartDate=effectiveStartDate;
this.effectiveEndDate=effectiveEndDate;
this.dataMap=dataMap;
这个。项目=项目;
这个。错误=错误;
}
@凌驾
公开募捐{
试一试{
调试(this.getClass(),“已开始项查找:”+
Thread.currentThread().getId());
查找(Id、Id、effectiveStartDate、effectiveEndDate、,
数据映射、项目、错误);
调试(this.getClass(),“项查找已完成:”+
Thread.currentThread().getId());
}
最后{
如果(闩锁!=null){
倒计时();
}
}
}
公共无效设置闩锁(倒计时闩锁){
this.latch=闩锁;
}
}

我猜有大量的上下文切换正在进行。我的建议是将ExecutorService从方法变量移动到服务(或控制器)类中的字段

private ExecutorService threadPoolExecutor=Executors.newFixedThreadPool(20);
public void myServiceMethod(){
列出工人名单;
if(StringUtils.isBlank(类型代码)){
工人=
ItemManagerHelper.通过ItemIdentifiers(Id、Id、,
有效开始日期、有效结束日期、错误、项目列表、数据映射);
}
否则{
workers=ItemManagerHelper.DeterminiteItemLookupWorkers ByItemType(Id,
ID、有效开始日期、有效结束日期、类型代码、错误、ItemUIList、,
数据地图);
}
CountDownLatch latch=新的CountDownLatch(workers.size());
for(可运行工作程序:工作程序){
((ItemLookupThread)worker);
threadPoolExecutor.submit(worker);
}
试一试{
等待(线程超时,时间单位为毫秒);
} 
捕捉(中断异常e){
错误(this.getClass(),e,“在等待
查找子线程完成。“);
} 
最后{
threadPoolExecutor.shutdown();
}
}

我猜有大量的上下文切换正在进行。我的建议是将ExecutorService从方法变量移动到服务(或控制器)类中的字段

private ExecutorService threadPoolExecutor=Executors.newFixedThreadPool(20);
public void myServiceMethod(){
列出工人名单;
if(StringUtils.isBlank(类型代码)){
工人=
ItemManagerHelper.通过ItemIdentifiers(Id、Id、,
有效开始日期、有效结束日期、错误、项目列表、数据映射);
}
否则{
workers=ItemManagerHelper.DeterminiteItemLookupWorkers ByItemType(Id,
ID、有效开始日期、有效结束日期、类型代码、错误、ItemUIList、,
数据地图);
}
CountDownLatch latch=新的CountDownLatch(workers.size());
for(可运行工作程序:工作程序){
((ItemLookupThread)worker);
threadPoolExecutor.submit(worker);
}
试一试{
等待(线程超时,时间单位为毫秒);
} 
捕捉(中断异常e){
错误(this.getClass(),e,“在等待
查找子线程完成。“);
} 
最后{
threadPoolExecutor.shutdown();
}
}

请分享更多详细信息-代码片段、您更改了什么、您如何使用闩锁、线程在做什么等等
private ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(20);


public void myServiceMethod() {

    List<Runnable> workers;

    if (StringUtils.isBlank(typeCode)) {
        workers =          
        ItemManagerHelper.determineItemLookupWorkersByItemIdentifiers(Id, ids,
        effectiveStartDate, effectiveEndDate, errors, ItemUIList, dataMap);
        }
    else {
         workers = ItemManagerHelper.determineItemLookupWorkersByItemType(Id, 
         ids,effectiveStartDate,effectiveEndDate, typeCode, errors, ItemUIList, 
         dataMap);
        }
    CountDownLatch latch = new CountDownLatch(workers.size());

    for (Runnable worker : workers) {
          ((ItemLookupThread) worker).setLatch(latch);
          threadPoolExecutor.submit(worker);
    }

    try {
          latch.await(threadTimeOut, TimeUnit.MILLISECONDS);
    } 
    catch (InterruptedException e) {
          error(this.getClass(), e, "Exception occurred while waiting for the 
               lookup child threads completion.");
    } 
    finally {
          threadPoolExecutor.shutdown();
    }
}