Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在游戏循环中等待未来任务完成_Java_Multithreading_Concurrency_Libgdx_Futuretask - Fatal编程技术网

Java 在游戏循环中等待未来任务完成

Java 在游戏循环中等待未来任务完成,java,multithreading,concurrency,libgdx,futuretask,Java,Multithreading,Concurrency,Libgdx,Futuretask,我想为昂贵的路径查找任务设置一个FutureTask。所以我创建了这个可调用的类 public class GetPath implements Callable<List<Coordinate>> { private Coordinate start; private Coordinate end; public GetPath(Coordinate start, Coordinate end) { this.start =

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

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;
    }
}
但这会产生一个
NullPointerException
我无法跟踪。我已经检查了我自己代码中的所有变量,似乎没有任何内容是空的。也许我误解了。或者,我应该将任务留给执行者来处理并使用执行者来确定任务是否完成,但我不确定如何完成

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)
//...
我只是想在另一个线程上运行一些昂贵的代码,而不中断我的主游戏循环。我不在乎它需要多长时间才能找到一条路径,这就是为什么我宁愿把它放在一个单独的线程中,然后尝试实现一个更好的pathfind算法,比如分层a*。我目前正在使用
gdx.ai.pfa.*
进行路径查找

打开当前程序时,有100个单元等待路径。每个游戏循环1个单元获得一个路径请求。我不确定这是否对我在这里的工作有任何影响。

如果您查看未来的
您将看到
get
等待任务完成。如果您在游戏循环中选中
isDone
,并在返回
true
后只调用
get
,那么您将异步运行。这就是为什么第二个代码块可以有效地单线程运行

在下一个示例中,它会更好地异步运行,但每次循环时都会调用它,这意味着您关闭了
ExecutorService
,但任务仍然完成,因此您可以再次调用
isDone
get
。第二次可能就是生成
NullPointerException
的原因。您很可能需要一些东西来阻止重复调用它,例如将
task
设置为null并检查
task=null&&task.isDone()

您还应该在程序开始时创建一个
ExecutorService
,然后重复使用,而不是不断创建一个然后关闭它


您还需要进一步考虑这一点,例如,如果您尝试在旧路径完成之前计算新路径,会发生什么情况?或者路径改变了?

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

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

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


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

path=(List)task.get()块,直到将来完成;这里的代码相当于只在同一个线程中运行它(除了您正在创建另一个线程)。顺便说一句,将任务声明为
FutureTask
,那么您就不需要强制转换原始返回类型。@AndyTurner我如何异步运行它?使用回调而不是等待任务。get()如何;不是返回“路径”,而是调用回调机制将路径传递给它。那么就不需要等待了。拥有一个单线程池一点也不傻。事实上,甚至还有一个专门针对该用例的特殊API调用:
executors.newSingleThreadedExecutor()
。假设您有生成一系列任务的东西。假设任务必须按照严格的顺序一个接一个地执行。但是,假设整个序列可以“在后台”执行……是的,我最终将使用单个执行器。但在我的示例中,我只在
task.isDone()
时关闭执行器。这在第一次循环完成后每次循环都是如此。我添加了更多信息。JustDanyul给出了答案。我试图对每个线程使用相同的探路器。谢谢你的关注!这可能就是正在发生的事情<代码>TestMap.pathFinder.searchNodePath(位置、目的地、新启发式实现()、结果路径)将更改。我将尝试在runnable中实现这一点。这确实消除了错误。它只是不能正常工作了,但我正在努力。但是如果地图改变了怎么办?我可能也应该在runnable中有一个深度副本。我确实让它工作了。因为我对每个线程使用相同的pathfinder,所以这会导致问题。我可能还需要在我的
Runnable
中生成一个节点图,因为映射是动态的。但这是另一个昂贵的计算,只有当地图在创建的路径上更改时才需要。谢谢很高兴听到您让它运行得这么快,并发问题可能会很棘手,因为调试很困难:我还没有完成它,并且已经阅读了关于它的可怕之处,所以我可能会遇到一些问题;)。
        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
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)
//...