共享对象并从主线程控制线程执行
我正在尝试解决非常简单的问题。我有一个主线程,它绘制一个框架,另一个线程(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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是典型的生产者-消费者问题。我建议您避免使用 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.