尝试加快此for循环的速度,但是我无法使用Callable实现

时间:2018-09-10 18:15:42

标签: java multithreading executorservice

这是顺序循环:

  private boolean canSpawnVehicle(SpawnPoint spawnPoint) {
// TODO: can be made much faster.
Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
for(VehicleSimView vehicle : vinToVehicles.values()) {
  if (vehicle.getShape().intersects(noVehicleZone)) {
    return false;
  }
}
return true;

}

这是我尝试通过执行程序服务和可调用的实现类进行线程化

  private boolean canSpawnVehicle(SpawnPoint spawnPoint) throws ExecutionException, InterruptedException {
  // TODO: can be made much faster.
  Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
  ExecutorService executor = Executors.newFixedThreadPool(6);
  Future<Boolean> future;
  for (VehicleSimView vehicle : vinToVehicles.values()) {
      future = executor.submit(new CanSpawnThread(vehicle, noVehicleZone));
      if(!future.get()){
          return false;
      }
  }
  executor.shutdown();
  return true;

}

这是线程类:

公共类CanSpawnThread实现Callable {

private VehicleSimView vehicle;
private Rectangle2D noVehicleZone;

public CanSpawnThread(VehicleSimView vehicle, Rectangle2D noVehicleZone){
    this.vehicle = vehicle;
    this.noVehicleZone = noVehicleZone;
}

public Boolean call() {
    boolean can = true;
    if (vehicle.getShape().intersects(noVehicleZone)){
        can = false;
    }
        return can;
}

}

3 个答案:

答案 0 :(得分:1)

您可以尝试使用parallelStream,前提是该列表具有足够的项目来证明线程合理。 我还没有测试过。

private boolean canSpawnVehicle(SpawnPoint spawnPoint) {
    Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
    Optional result = vinToVehicles.values().parallelStream().filter(v -> !v.getShape().intersects(noVehicleZone)).findFirst();

    return !result.isPresent();
}

答案 1 :(得分:0)

看看循环:

for (VehicleSimView vehicle : vinToVehicles.values()) {
      future = executor.submit(new CanSpawnThread(vehicle, noVehicleZone));
      if(!future.get()){
          return false;
      }
  }

您要提交给执行者,然后等待将来完成,然后继续并提交下一个。这仍然只是一个顺序循环。

将所有可调用对象提交给执行者,将Future存储在列表中,然后检查列表中的元素是否已完成。

或者更好的方法是使用CompletionService,这将按照期货的完成顺序将期货返还给您。一旦找到返回假值的Future,请取消所有其他内容并返回。

答案 2 :(得分:0)

您提交任务并等待完成。这样,每件事都是顺序的,因此您无法提高性能。提交所有任务,然后等待完成并检查结果。像这样:

 private boolean canSpawnVehicle(SpawnPoint spawnPoint) throws ExecutionException, InterruptedException {
  // TODO: can be made much faster.
  Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
  ExecutorService executor = Executors.newFixedThreadPool(6);
  List<Future<Boolean>> futures = new ArrayList();
  for (VehicleSimView vehicle : vinToVehicles.values()) {
      futures.add(executor.submit(new CanSpawnThread(vehicle, noVehicleZone)));          
  }
  for(Future<Boolean> future : futures) {
       if(!future.get()) {
          return false;
       }
  }
  executor.shutdown();
  return true;
}