Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.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_Libgdx - Fatal编程技术网

Java 异步执行器不’;似乎不是异步的

Java 异步执行器不’;似乎不是异步的,java,multithreading,libgdx,Java,Multithreading,Libgdx,这个问题经过编辑,尽可能多地提供关于这个问题的信息,就像有人建议我应该做的那样。现在有悬赏了,这似乎是正确的做法。祝大家好运 别忘了,如果你觉得有什么我没有包括在内的话,你可以问更多的问题 介绍 我正在开发一个系统,当角色使用各种不同的噪音四处走动时,程序性地生成地形。世界本身有三个维度,尽管它被视为游戏的内部 对于那些习惯于按程序生成地形的人,您会意识到,为了避免在渲染器线程中造成延迟峰值,有必要使用多线程。这正是我一直在尝试做的事情,在的以及同一个库的帮助下,这是一个在asynceducer

这个问题经过编辑,尽可能多地提供关于这个问题的信息,就像有人建议我应该做的那样。现在有悬赏了,这似乎是正确的做法。祝大家好运

别忘了,如果你觉得有什么我没有包括在内的话,你可以问更多的问题

介绍 我正在开发一个系统,当角色使用各种不同的噪音四处走动时,程序性地生成地形。世界本身有三个维度,尽管它被视为游戏的内部

对于那些习惯于按程序生成地形的人,您会意识到,为了避免在渲染器线程中造成延迟峰值,有必要使用多线程。这正是我一直在尝试做的事情,在的以及同一个库的帮助下,这是一个在
asynceducer
提供的线程上运行的任务

private class RegionLoader implements AsyncTask<Object>
{
    private List<Region> regions;
    private List<ToSendInner> toSends;

    public RegionLoader(
            List<Region> regions, 
            List<ToSendInner> toSends)
    {
        this.regions = regions;
        this.toSends = toSends;
    }

    @Override
    public Object call() throws Exception
    {
        // Generates the ‘Region’s it has been given inside the constructor
        // ...

        return null;
    }
}
问题 我的问题是
AsyncExecutor
看起来根本不是异步的。它会在我的渲染器线程中导致延迟峰值,理论上,这可能是由于它使用了渲染器线程也使用的资源。然而,问题是渲染器线程生成新的“块”——我称之为
asynceducer
然后处理的区域。在
异步执行器
完全生成该资源之前,不允许渲染器线程渲染该资源

private class RegionLoader implements AsyncTask<Object>
{
    private List<Region> regions;
    private List<ToSendInner> toSends;

    public RegionLoader(
            List<Region> regions, 
            List<ToSendInner> toSends)
    {
        this.regions = regions;
        this.toSends = toSends;
    }

    @Override
    public Object call() throws Exception
    {
        // Generates the ‘Region’s it has been given inside the constructor
        // ...

        return null;
    }
}
RegionHandler
我有一个名为
RegionHandler
的类,它在播放器移动的方向上放置新的区域,并从相反方向删除区域,以便程序一次不必知道超过13 x 9个区域

下面是一段简短的代码,解释它是如何工作的-这里的注释是为了简化对不同代码的讨论:

// These ‘if’s are triggered when the player moves
// to a certain position
if(addLeft)
{
    // Adds new regions to the left and removes to the right
    // ...

    // Submit ‘RegionLoader’ task to ‘asyncExecutor’
    // with regions that needs be generated as well as ‘toSends’ which is
    // also part of that generation
    asyncExecutor.submit(new RegionLoader(toGenRegions, toSends));      
}
else if(addRight)
{
    // Adds new regions to the right and removes to the left
    // ...

    // Same as previous ‘submit’ to the ‘asyncExecutor’
    asyncExecutor.submit(new RegionLoader(toGenRegions, toSends));
}

if(addBottom)
{
    // Adds new regions to the bottom and removes to the top
    // ...

    // Same as previous ‘submit’ to the ‘asyncExecutor’
    asyncExecutor.submit(new RegionLoader(toSend, toSends));
}
else if(addTop)
{
    // Adds new regions to the top and removes from the bottom
    // ...

    // Same as previous ‘submit’ to the ‘asyncExecutor’
    asyncExecutor.submit(new RegionLoader(toSend, toSends));
}
asyncExecutor
实际上是一个
asyncExecutor
,而
RegionLoader
实现了
AsyncTask
接口。我已经测试了这段代码运行多长时间,这段代码从来不会超过一毫秒

区域
在列表中处理:

List<List<Region>> regions;
一旦
call()
完成,它会将
布尔值设置为
true
,允许呈现特定的
区域

此外 虽然
AsyncExecutor
是异步的,但它在渲染器线程内每隔一段时间就会导致延迟峰值。如前所述,这可能是由于
asynceducer
使用与渲染器线程相同的资源造成的,但渲染器线程仅在允许的情况下渲染
区域
,因此我看不出这是导致延迟峰值的原因

到目前为止我都试过了 我曾尝试使用常规Java线程,但由于LibGDX支持Android开发,而且Android在多线程方面没有相同的功能,这些线程可能无法正常工作,但我可能真的错了

此外
也许有人在游戏开发生涯中也遇到过类似的问题?如果是这样的话,也许有人能给我指出正确的方向?

我不记得Android和线程有什么问题,我搜索过,但没有找到任何东西。你应该测试一下

我将假设生成区域与openGL无关。所以你不必在主线程上运行它

试试这个:Thread+Gdx.app.postRunnable()

如果您查看AsyncExecutor的源代码,就会发现它的功能完全相同。但只是它不会让第二个runnable同时运行

注意:AsyncExecutor的实现在gwt后端更改为立即执行。因为我猜的局限性。您可能不应该以gwt为目标

试试看,让我知道。如果主线程仍然挂起,那是因为您在//提交该内容部分中所做的操作。发布更多的代码,还不足以理解问题的根源


编辑:还可以使用Gdx.graphics.getDeltaTime()查看是否真的存在挂起。它可能是由其他原因引起的,因此排除其他可能性,找出真正的原因是否是此任务。

我将研究垃圾收集的效果,因为您似乎正在向任务传递新的区域对象。尝试重新使用/重新填充现有区域。

您可以降低其优先级,或者将线程数(MaxConcurent)减少到少于核心数。哦,是的,我忘了提到这一点-我已经在使用
1
作为
maxConcurrent
。是否立即调用
获取结果?还是仅仅是一个
无效的任务?@jornverne我做了一个小小的编辑,应该可以回答你的问题。然而,如果不是这样的话,你可以自由地扩展你的问题。我对整个
AsyncExecutor
这件事还不太熟悉。这可能是造成延迟的原因,如果一个线程必须等待另一个线程,那么并行没有任何好处。您可以尝试,而不是一次完成整个批处理,执行一个步骤,然后释放锁,以便渲染线程可以继续渲染,只是不会同时添加所有内容。