【问题标题】:LibGDX: Create new scene2d Object inside another thread?LibGDX:在另一个线程中创建新的 scene2d 对象?
【发布时间】:2018-04-28 20:10:36
【问题描述】:

我有一个数据库,用于存储例如TextureAtlas 的图像键。因为数据库查询不应该阻塞主线程,所以查询在另一个线程上执行。

现在我想创建一个场景 2d 演员并将其返回,以便显示。

new Thread() {
        @Override
        public void run() {
            String resultOfQuery = ...;
            final Image image = new Image(atlas.findRegion(resultOfQuery));

            Gdx.app.postRunnable(new Runnable() {
                @Override
                public void run() {
                    listener.onImageCreated(image);
                }
            }); 
        }
    }.start();

如您所见,我正在新线程中创建图像,然后将其传递给主线程。但 libGDX wiki 声明:

你不应该对任何与图形或音频相关的东西执行多线程操作,例如。使用来自多个线程的 scene2D 组件。

我是否必须在主线程上创建演员到舞台?或者,如果我在另一个线程中创建它,然后将它添加到主线程的舞台上,可以吗?

【问题讨论】:

    标签: java multithreading libgdx thread-safety scene2d


    【解决方案1】:

    我在上面看到的唯一潜在问题是在 atlas 上调用 findRegion,这不是线程安全的。但是,如果您知道在其他地方使用地图集时您的线程没有运行,那就没问题了。如果您有多个查询都可能访问图集,那么您就会遇到问题。或者,如果您在游戏循环中调用 atlas 方法。

    当然,您可以简单地使用无参数的 Image 构造函数并将其传递给游戏线程可运行的区域。那么你就没有什么可担心的了。

    【讨论】:

    • 那么wiki中的句子到底是什么意思呢?他们所说的“永远不要在 [...] scene2d 组件上执行多线程操作”是什么意思?
    • 不要同时从多个线程访问它们。由于在将图像添加到舞台后没有使用后台线程来访问图像,因此您没有这样做。您在一个线程上创建它,然后将其添加到主游戏线程中的阶段。两个线程永远不可能同时访问该图像。
    • 但是 wiki 中的那一段具有误导性,因为它将 LibGDX 对象不是线程安全的(不能安全地从多个并发线程中使用)这一事实与 图形化 的事实混为一谈不能从后台线程中使用对象。这是因为只有主游戏线程可以访问 OpenGL 调用。所以你不能实例化一个新的纹理或尝试在后台线程中批量绘制一些东西
    • 在您上面的回答中,您提到只要未在其他地方使用图集,就可以在另一个线程中使用 findRegion。这是为什么?我看不出这会是个问题的原因。
    • @Antict 也许没关系,也许不是。它没有被标记为线程安全类,所以可以肯定地说它不是。您可以仔细检查源代码,看看findRegion 在多线程情况下是否会出现问题。根据它的实现方式,它可能会。它可能涉及迭代一个数组,如果由多个线程同时完成,这可能会导致异常。即使它现在是安全的,它也可能在更高版本的 LibGDX 中被破坏。
    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多