我正在尝试解决相当简单的问题。我有一个主线程,它绘制一个框架,另一个线程(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/