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

发布于 2025-01-07 13:39:24 字数 1361 浏览 1 评论 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很陌生,我觉得有更好、更安全的方法来实现它。你能给我一些建议吗?谢谢。

I am trying to solve quite easy problem. I have a main thread, which draws a frame and another thread(FrameThread) that prepares this frame every time. Both threads should share same MyFrame object. I want to control FrameThread from the main thread, i.e.: MyFrame is ready -> draw it in main thread -> keep FrameThread running. Currently i did following:

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;
    }
}    

After that i create 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();
    }
}

And finally main thread:

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

So my goal is: FrameThread executes in background and stops right after frame is ready. I am very novice in Java, and i feel there is much better and safer way to achieve it. Could you give me an advice about it? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谢绝鈎搭 2025-01-14 13:39:24

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

相反,请查看 BlockingQueue 界面并使用注释中的示例作为指导。这似乎正是您正在寻找的。

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

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

This is the classic producer-consumer problem. I suggest that you avoid using wait() and notify() because they are difficult to get right, even for seasoned developers.

Instead, check out the BlockingQueue interface and use the example in the comments as a guide. This seems to be exactly what you're looking for.

If it is required that no more than one frame is generated in advance, then use an ArrayBlockingQueue with a capacity of 1.

I should also mention that in both your example and the BlockingQueue example in the link above, semantics for shutting down the producer and consumer threads are not explained. You will need to add a stopping mechanism to be complete, otherwise your program will not shut down on its own, even after the main thread has died.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文