Re[2]: потоки. стоп старт потока в Runnable ожидающего ин
От: KRA Украина  
Дата: 12.06.09 12:07
Оценка:
Здравствуйте, KRA, Вы писали:

KRA>Здравствуйте, objet, Вы писали:


KRA>явные проблемы

KRA>1. вызывается wait и на нём поток будет висеть вечно. Чтоб исправить нужно в setItem вызывать notify. Поле threadSuspended — вообще не нужно. Похоже Вы не правильно понимаете, что делает wait.
KRA>2. некоторые item-ы могут теряться. Если записывать их быстрей чем обрабатывать, то последующий просто затрёт предыдущий. Нужно хранить очередь item-ов ожидающих обработки.

И вдогонку, тут вообще можно обойтись без блокировок. Вот пример

public abstract class BackgroundEventProcessor<Event> implements Runnable {
    protected final Log log = LogFactory.getLog(getClass());
    private final Queue<Event> events = new ConcurrentLinkedQueue<Event>();
    private Thread worker;

    private Long processingTimeout;

    public void stop() {
        log.info("interrupting worker...");
        worker.interrupt();
    }

    @Monitor(startEvent = EventType.STARTED, endEvent = EventType.STOPPED)
    public void run() {
        log.info("starting worker...");
        while (true) {
            try {
                processEvents();
            } catch (InterruptedException e) {
                log.info("worker interrupted");
                break;
            }
        }
        log.info("worker stopped");
    }

    @Monitor(exceptions = { @ExceptionEvent(event = EventType.STOPPING, exception = InterruptedException.class) } )
    private void processEvents() throws InterruptedException {
        Event event;
        while((event = events.poll()) != null) {
            onEvent(event);
            if (Thread.interrupted())
                throw new InterruptedException();
        }

        Thread.sleep(processingTimeout);
    }

    protected abstract void onEvent(Event event);

    public void start() {
        worker = new Thread(this);
        worker.start();
    }


    public void setProcessingTimeout(Long processingTimeout) {
        this.processingTimeout = processingTimeout;
    }

    protected void addEvent(Event event) {
        events.add(event);
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.