为了账号安全,请及时绑定邮箱和手机立即绑定

试图加速这个 for 循环,但我不能使用 Callable 实现

试图加速这个 for 循环,但我不能使用 Callable 实现

一只名叫tom的猫 2021-09-12 16:45:59
这是顺序循环:  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 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

您可以尝试使用 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();

}


查看完整回答
反对 回复 2021-09-12
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

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


 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;

}


查看完整回答
反对 回复 2021-09-12
?
精慕HU

TA贡献1845条经验 获得超8个赞

看循环:


for (VehicleSimView vehicle : vinToVehicles.values()) {

      future = executor.submit(new CanSpawnThread(vehicle, noVehicleZone));

      if(!future.get()){

          return false;

      }

  }

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


将所有可调用对象提交给执行程序,将Futures存储在列表中,然后检查列表的元素以查看它们是否已完成。


或者,更好的是使用 a CompletionService,它会按照它们完成的顺序返回给你。一旦你找到一个返回 false 的 Future,取消所有其他的并返回。


查看完整回答
反对 回复 2021-09-12
  • 3 回答
  • 0 关注
  • 166 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信