Java: Stuck in the while loop in the background th

2019-09-16 06:07发布

I'm using LibGDX AsyncExecutor and the following function is called in a background thread. 'tasksForTheMainThread' is the static array of Runnable, which executes its not yet executed elements during each call of the update function in the main thread. The function 'createBox' of 'modelBuilder' creates and returns an object of the class 'Model'.

Briefly explaining, this code executes in the second thread and sends a piece of code (function 'run()') to be used in the first thread. After it's sent, the second thread is frozen until the moment the code in "run()" is completed and the Model object is created (or at least it's supposed to be like that).

However, it works as expected only when the while loop (which just waits until the object is created in the main thread) contains the logging bit (Gdx.app.log("TAG","2");). When it's empty, the second thread freezes forever and never reaches 'point A' even after the creation of the Model object.

Why and how logging can influence that? And why isn't the programme working without it?

void secondThreadFunction()
{
    Model model = null;

    ChunkManager.tasksForTheMainThread.add(new Runnable()
    {
                    @Override
                    public void run()
                    {
                            model = modelBuilder.createBox(size.x, size.y, size.z, GL20.GL_LINES,
                                    new Material(ColorAttribute.createDiffuse(Color.YELLOW)),
                                    VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal);
                    }
     });

     while (model == null)
     {
            //Gdx.app.log("TAG","2");
     }

      //point A
}

1条回答
叛逆
2楼-- · 2019-09-16 06:56

You cannot modify a local variable that has been captured to an inner class. Since it has been "captured", you will operate on a copy of the value and it will never be non-null, causing the endless loop. Also note that you are busy-waiting in a tight loop. It might be better to use a Future of some kind.

void secondThreadFunction()
{
    AtomicReference<Model> model = new AtomicReference<Model>();

    ChunkManager.tasksForTheMainThread.add(new Runnable()
    {
                    @Override
                    public void run()
                    {
                            model.set(modelBuilder.createBox(size.x, size.y, size.z, GL20.GL_LINES,
                                    new Material(ColorAttribute.createDiffuse(Color.YELLOW)),
                                    VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal));
                    }
     });

     while (model == null)
     {
            //Gdx.app.log("TAG","2");
     }

      //point A
}
查看更多
登录 后发表回答