Kael
Kael

Reputation: 25

Sharing object and controlling thread execution from main thread

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.

Upvotes: 0

Views: 299

Answers (1)

Nate
Nate

Reputation: 557

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.

Upvotes: 1

Related Questions