gpt4 book ai didi

java - 在游戏循环中等待 FutureTask 完成

转载 作者:行者123 更新时间:2023-11-30 10:53:13 25 4
gpt4 key购买 nike

我想为昂贵的路径查找任务设置一个 FutureTask。所以我创建了这个 Callable 类。

public class GetPath implements Callable<List<Coordinate>> {

private Coordinate start;
private Coordinate end;

public GetPath(Coordinate start, Coordinate end) {
this.start = start;
this.end = end;
}

@Override
public List<Coordinate> call() throws Exception {

IndexedNodeImplementation location = TestMap.mapgraph.getNodeByCoord(start.x, start.y);
IndexedNodeImplementation destination = TestMap.mapgraph.getNodeByCoord(end.x, end.y);
GraphPathImplementation resultPath = new GraphPathImplementation();

List<Coordinate> path = new ArrayList<Coordinate>();

TestMap.pathFinder.searchNodePath(location, destination, new HeuristicImplementation(), resultPath);

if (resultPath.getCount() > 0)
{
for (int i = 1; i < resultPath.getCount(); i++)
{
path.add(new Coordinate(resultPath.get(i).origin(), true));
}
}
return path;
}
}

当我在构造函数中看到的示例中执行此操作时,它仍然“等待”直到任务完成。虽然这有效,但我仍然遇到帧丢失,就好像我会在没有线程的情况下这样做一样。

executor = Executors.newFixedThreadPool(1);
task = new FutureTask(new GetPath(creature.getLocation(), coordinate));
//TestMap.executor.execute(task);

executor.execute(task);

try {
path = (List<Coordinate>)task.get();
} catch (InterruptedException e) {
System.out.println("Interrupted Exception");
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("Execution Exception"); // <---
e.printStackTrace();
}

executor.shutdown();
//Works but is basically the same as just looking up a path in the main thread.

我知道拥有一个线程池非常愚蠢,但我是新手。无论如何,我尝试为每个对象使用相同的 ExecutorService 一个更大的池,但没有成功。

由于此方法在完成之前仍会保留程序,因此我尝试在游戏循环中观看 FutureTask。完成后,我填充路径列表并继续代码。

        if (task.isDone())
{
try {
path = (List<Coordinate>)task.get();
} catch (InterruptedException e) {
System.out.println("Interrupted Exception");
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("Execution Exception");
e.printStackTrace();
}
executor.shutdown();
//TestMap.executor.shutdown();
}
else
{
return false;
}
//Continue with code and work with path which should now contain elements

但这给出了一个我无法追踪的 NullPointerException。我已经检查了我自己代码中的所有变量,似乎没有什么是空的。也许我误解了task.isDone .或者也许我应该将任务留给执行者来处理并使用执行者来确定任务是否完成,但我不确定如何完成。

java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.perform(GoTo.java:55)
//...

我只是想在不中断主游戏循环的情况下在另一个线程上运行一些昂贵的代码。我不在乎它找到一条路径需要多长时间,这就是为什么我宁愿把它放在一个单独的线程中,然后尝试实现一个更好的寻路算法,比如分层 A*。我目前正在使用 gdx.ai.pfa.* 进行寻路。

打开当前程序后,有 100 个单元在等待路径。每个游戏循环 1 个单元得到一个路径请求。我不确定这是否会影响我在这里所做的事情。

最佳答案

如果您的路径查找 Runnable 在同步运行时运行良好,但在异步运行时运行不正常(您的第二个示例)。我相信您的问题出在您的 Runnable 中,您正在尝试访问某些资源,该资源在您访问时为 null。

您基本上在清空(或处置)资源的代码行与 Runnable 中需要访问它的代码之间存在竞争条件。换句话说,当您同步运行它时,Runnable 总是“首先到达那里”,因为程序的其余部分正在等待它完成。在您的情况下,当它异步时,处理/清空代码在 Runnable 获取资源之前执行。

您截断了堆栈跟踪,但最后一行提到了 GoTo.java 中的 perform 方法

您从 Runnable 外部对某些资源执行某些操作,这意味着,在执行 runnable 时,它​​会尝试访问 null 的内容。

关于java - 在游戏循环中等待 FutureTask 完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34089407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com