【问题标题】:Sharing object and controlling thread execution from main thread从主线程共享对象和控制线程执行
【发布时间】:2012-02-19 12:29:55
【问题描述】:

我正在尝试解决相当简单的问题。我有一个主线程,它绘制一个框架和另一个线程(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 的新手,我觉得有更好、更安全的方法来实现它。你能给我一个建议吗?谢谢。

【问题讨论】:

  • @HovercraftFullOfEels 你是对的先生。
  • @Kael:你的代码对我来说似乎很不寻常——但我不是线程专家。你的程序是图形用户界面吗?这是一个 java.awt.Frame 吗?如果是这样,为什么不使用 Swing 和 javax.swing.JFrames?如果 GUI 考虑使用 SwingWorkers。如果您没有很快得到任何体面的答案,请考虑尽可能提供更多详细信息。
  • @Hovercraft Full Of Eels:我想我应该重命名它。这只是纯 Java,没有额外的框架。
  • @Kael:感谢您的澄清。如果人们使用在 Java 核心库中已经有对应的类名,它总是让我(可能还有其他人)感到困惑,我建议人们尽可能避免这种情况。

标签: java concurrency mutual-exclusion


【解决方案1】:

这是经典的生产者-消费者问题。我建议您避免使用 wait() 和 notify(),因为它们很难正确使用,即使对于经验丰富的开发人员也是如此。

相反,请查看@987654321@ 接口并使用 cmets 中的示例作为指导。这似乎正是您想要的。

如果要求提前生成不超过一帧,则使用容量为1的@987654322@

我还应该提到,在您的示例和上面链接中的 BlockingQueue 示例中,都没有解释关闭生产者和消费者线程的语义。您将需要添加一个停止机制才能完成,否则您的程序将不会自行关闭,即使在主线程死亡后也是如此。

【讨论】:

    猜你喜欢
    • 2012-12-13
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2011-04-06
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多