这是顺序循环:
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;
}
}
您可以尝试使用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();
}
看看循环:
for (VehicleSimView vehicle : vinToVehicles.values()) {
future = executor.submit(new CanSpawnThread(vehicle, noVehicleZone));
if(!future.get()){
return false;
}
}
您正在向执行人提交,然后等待将来完成,然后继续并提交下一个。这仍然只是一个顺序循环。
将所有可调用对象提交给执行程序,将Future
s存储在列表中,然后检查列表中的元素以查看它们是否已完成。
或者,更好的是,使用CompletionService
,它将按照它们完成的顺序返回Futures。一旦找到返回false的Future,取消所有其他并返回。
您提交任务并等待完成任务。通过这种方式,每件事都是连续的,因此无法改善您的表现。提交所有任务,然后等待完成并检查结果。像这样:
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;
}