Совместное использование объекта и управление выполнением потока из основного потока - PullRequest
0 голосов
/ 19 февраля 2012

Я пытаюсь решить довольно простую проблему.У меня есть основной поток, который рисует кадр, и другой поток (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, и я чувствую, что есть гораздо лучший и безопасный способ достичь этого.Не могли бы вы дать мне совет по этому поводу?Спасибо.

1 Ответ

1 голос
/ 25 апреля 2012

Это классическая проблема производитель-потребитель. Я предлагаю вам избегать использования wait () и notify (), потому что их трудно понять, даже опытным разработчикам.

Вместо этого проверьте интерфейс <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html" rel="nofollow">BlockingQueue</a> и используйте пример в комментариях в качестве руководства. Кажется, это именно то, что вы ищете.

Если требуется, чтобы заранее было сгенерировано не более одного кадра, используйте <a href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html" rel="nofollow">ArrayBlockingQueue</a> с емкостью 1.

Я должен также упомянуть, что как в вашем примере, так и в примере BlockingQueue по ссылке выше семантика для отключения потоков производителей и потребителей не объясняется. Вам нужно будет добавить механизм остановки, чтобы завершить его, иначе ваша программа не будет закрыта сама по себе, даже после того, как основной поток завершится.

...