0

I'm using libgdx for a game I'm writing, where I have another thread that needs to update the graphics thread. I was getting crashes as libgdx is not thread safe (intentionally) and I was allowing the other thread to directly modify a variable in the graphics thread.

The libgdx docs suggest something similar to the following code. It's basically a closure containing the incoming information, which is then processed when the graphics thread gets to it.

I've modified it to declare the runnable outside of the the listener in the hopes that I could avoid garbage collection, but it occurs to me that I may have created a race condition now where runnable could be overwritten prior to the graphics thread consuming the previous information?

So far I've been able to avoid garbage collection everywhere else, and my game is also utilizing the low-latency audio bindings in Android so garbage collection is really my enemy.

Any suggestions?

private Runnable runnable;
private SomeListener listener = new SomeListener() {
    @Override
    public void messageIn(final String source, final String s, final Object... l) {
        runnable = new Runnable() {
            @Override
            public void run() { getWorkspace().messageIn(s,l); }
        };
        Gdx.app.postRunnable(runnable);
    }

};

4

2 回答 2

1

由于您正在开发游戏,我建议您将所有消息发布到队列中,然后根据需要在游戏循环中使用。

于 2013-07-16T17:02:38.700 回答
1

我已经修改它以在侦听器之外声明可运行对象,希望可以避免垃圾收集,但我突然想到我现在可能已经创建了一个竞争条件,其中可运行对象可以在图形线程消耗之前被覆盖以前的信息?

是的,这肯定会发生。此外,您不能使用ThreadLocals ,因为它将是处理回调与可运行的不同线程。

你可以做的是创建一个BlockingQueueRunnable。一旦 run 方法完成,就可以将自己置于要重用Runnable的末尾。BlockingQueuemessageIn(...)调用该方法时,它会调用queue.poll()并且仅在队列中没有方法时创建一个新方法。这会增加内存同步,但会降低 GC 带宽。它可能不会给你带来太多好处。

您可能会考虑运行内存分析器以确保这是您应该集中重构以尝试降低内存使用量的地方。

于 2013-07-16T18:08:47.777 回答