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



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

例:

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

我正在使用执行器服务来实现异步执行机制和用于线程同步的倒计时锁存器

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

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

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();
}

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;
  }
}

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

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();
    }
}

最新更新