2012-02-19 89 views
0

我正試圖解決相當容易的問題。我有一個主線程,它繪製一個框架和另一個線程(FrameThread),每次都準備這個框架。兩個線程應共享相同的MyFrame對象。我想從主線程控制FrameThread,即:MyFrame已準備就緒 - >在主線程中繪製 - >保持FrameThread運行。目前,我沒有以下內容:共享對象並從主線程中控制線程執行

private class FrameEngine 
{ 
    private boolean isFrameReady = false; 
    private MyFrame frame; 

    public synchronized void generateFrame() 
    { 
     while(isFrameReady) 
      wait(); 
     frame = FrameGenerator.nextFrame(); 
     isFrameReady = true; 
     notifyAll(); 
    } 

    public synchronized MyFrame getFrame() 
    { 
     while(!isFrameReady) 
      wait(); 
     isFrameReady = false; 
     notifyAll(); 
     return frame; 
    } 
}  

之後,我創建FrameThread:

private class FrameThread implements Runnable 
{ 
    private final FrameEngine frame_eng; 

    public FrameThread(FrameEngine engine) 
    { 
     frame_eng = engine; 
    } 
    @Override 
    public void run() 
    { 
     while(true) 
      frame_eng.generateFrame(); 
    } 
} 

最後主線:

FrameEngine frame_engine = new FrameEngine(); 
Thread frameThread = new Thread(new FrameThread(frame_engine)); 
frameThread.start(); 
... 
while(true) 
{ 
    ... 
    drawFrame(frame_engine.getFrame()); 
    ... 
} 

所以我的目標是:FrameThread執行的背景,並在之後停止框架已準備就緒。我在Java中是新手,我覺得有更好更安全的方法來實現它。你能給我一個關於它的建議嗎?謝謝。

+1

@HovercraftFullOfEels你是對的先生。 – Juvanis 2012-02-19 12:40:01

+0

@Kael:你的代碼對我來說似乎不尋常 - 但我不是線程專家。您的程序是否以任何方式成爲GUI?這是一個java.awt.Frame嗎?如果是這樣,爲什麼不使用Swing和javax.swing.JFrames?如果GUI考慮使用SwingWorkers。如果您很快就沒有得到任何體面的答案,請考慮儘可能提供更多細節。 – 2012-02-19 12:41:29

+1

@ Hovercraft充滿鰻魚:我想我應該重新命名它。這只是純粹的Java,沒有額外的框架。 – Kael 2012-02-19 12:44:56

回答

1

這是一個典型的生產者 - 消費者問題。我建議你避免使用wait()和notify(),因爲即使對於經驗豐富的開發人員來說,他們也很難得到正確的結果。

取而代之,請查看BlockingQueue界面,並使用註釋中的示例作爲指導。這似乎正是你要找的。

如果需要的是不超過一個幀被預先生成,然後使用ArrayBlockingQueue,容量1

我還要提到的是在你的例子和上面的鏈接的BlockingQueue例如既有,關閉生產者和消費者線程的語義沒有解釋。您需要添加停止機制才能完成,否則即使在主線程死亡後,您的程序也不會自行關閉。