使用SingleThreadExecutor在任务之间等待

The*_*eLQ 2 java concurrency multithreading

我试图(简单地)创建一个阻塞线程队列,当提交任务时,方法等待直到完成执行.困难的部分是等待.

这是我的12:30 AM代码,我认为是矫枉过正:

public void sendMsg(final BotMessage msg) {
    try {
        Future task;
        synchronized(msgQueue) {
            task = msgQueue.submit(new Runnable() {
                public void run() {
                    sendRawLine("PRIVMSG " + msg.channel + " :" + msg.message);
                }
            });
            //Add a seperate wait so next runnable doesn't get executed yet but
            //above one unblocks
            msgQueue.submit(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(Controller.msgWait);
                    } catch (InterruptedException e) {
                        log.error("Wait to send message interupted", e);
                    }
                }
            });
        }
        //Block until done
        task.get();
    } catch (ExecutionException e) {
        log.error("Couldn't schedule send message to be executed", e);
    } catch (InterruptedException e) {
        log.error("Wait to send message interupted", e);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,那里有很多额外的代码,只是让它在任务之间等待1.7秒.那里有更简单,更清洁的解决方案,还是这样?

Joh*_*int 5

好的,这是一个想法.您可以使用ScheduledExceutorService,它将记住您上次执行runnable并相应地延迟下一次执行,超过最大睡眠时间(此处硬编码为1700).

    //@GuardedBy("msgQueue")
Date mostRecentUpdate = new Date();

public void sendMsg(final BotMessage msg) {
    try {
        Future task;
        synchronized (msgQueue) {               
            long delta = new Date().getTime() - mostRecentUpdate.getTime();
            task = msgQueue.schedule(new Runnable() {
                public void run() {
                    sendRawLine("PRIVMSG " + msg.channel + " :" + msg.message);
                }
            }, delta <= 1700 ?1700 : 0, TimeUnit.MILLISECONDS);

            mostRecentUpdate = new Date();
        }
        // Block until done
        task.get();
    } catch (ExecutionException e) {
        log.error("Couldn't schedule send message to be executed", e);
    } catch (InterruptedException e) {
        log.error("Wait to send message interupted", e);
    }
}
Run Code Online (Sandbox Code Playgroud)