2016-05-31 53 views
0

我正在使用LibGDX AsyncExecutor,並且在後臺線程中調用以下函數。 'tasksForTheMainThread'是Runnable的靜態數組,它在主線程的每次更新函數調用期間執行尚未執行的元素。 'modelBuilder'的函數'createBox'創建並返回類'Model'的一個對象。Java:陷入後臺線程中的while循環

簡單解釋一下,這段代碼在第二個線程中執行併發送一段代碼(函數'run()')用於第一個線程。發送之後,第二個線程被凍結,直到「run()」中的代碼完成並且Model對象被創建(或者至少它應該是這樣)。

但是,它只有在while循環(它只是等待直到在主線程中創建該對象)包含記錄位(Gdx.app.log("TAG","2");)時才按預期工作。當它是空的時候,第二個線程永遠凍結,並且即使在創建Model對象之後也永遠不會到達「點A」。

爲什麼和如何記錄可以影響呢?爲什麼沒有它的程序沒有工作?

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 
} 
+0

不應該'model'是一個'volatile'?這可能實際上是問題......與並行內核和日誌觸發同步有關。第二個線程沒有做任何事情,所以可能永遠不會獲得數據的更新視圖,因爲'model'不是'volatile'。另外,上面的代碼不可編譯,因爲'model'不是成員或'final'。 – Tenfour04

回答

0

您不能修改捕獲到內部類的局部變量。由於它已被「捕獲」,因此您將在該值的副本上進行操作,並且它永遠不會是非 - 無限循環。還要注意,你正在忙碌 - 等待一個緊密的循環。使用某種Future可能會更好。

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 
} 
+0

那麼爲什麼它在登錄循環時工作呢? –

+0

你確定'Model model'是一個局部變量而不是類成員嗎?在後面的例子中,可能是'Gdx.app.log()'有一個內存屏障(例如'synchronized'),這可能需要反映另一個線程上的更改。 –

+0

你說得對。這是該班的一個領域。 –