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
这件事还不太熟悉。这可能是造成延迟的原因,如果一个线程必须等待另一个线程,那么并行没有任何好处。您可以尝试,而不是一次完成整个批处理,执行一个步骤,然后释放锁,以便渲染线程可以继续渲染,只是不会同时添加所有内容。