java - 共享对象并从主线程控制线程执行

标签 java concurrency mutual-exclusion

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

最佳答案

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

相反,请查看 <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html" rel="noreferrer noopener nofollow">BlockingQueue</a>界面并使用注释中的示例作为指导。这似乎正是您正在寻找的东西。

如果要求提前生成不超过一帧,则使用 <a href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html" rel="noreferrer noopener nofollow">ArrayBlockingQueue</a>容量为1。

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

关于java - 共享对象并从主线程控制线程执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9349146/

相关文章:

c - 如何提供一系列交错线程来表明代码中断并且没有提供完美的同步?

java - 为什么这个程序会无限循环运行?相互排斥

java - 一个 Spring PropertyPlaceholderConfigurer 可以配置另一个 Spring PropertyPlaceholderConfigurer 吗?

java - 实现秒表

java - Java源代码生成中的霍夫曼代码解码器编码器

java - 新线程和调用线程都会被阻塞 Java Semaphore

java - 监控、调试和跟踪 CompletableFuture 任务

c - 为什么 CompareAndSwap 比 TestAndSet 更强大?

javascript - Play Framework 1.3.2 中的 Multi-Tenancy 特定国际化

java - 使用 com sun JNA : undefined symbol: GetDesktopWindow 进行屏幕捕获的问题