java - 在指定的超时后从一个线程执行多个 Runnable

标签 java multithreading concurrency

我想安排 Runnables 并从同一线程中依次执行它们,但不能更早,然后在指定的超时后执行。有标准的方法吗?

这是我的代码:

public class DelayedExecutor {
    private final long           _timeout;
    private final List<Runnable> _tasks = new LinkedList<>();
    private final ThreadFactory  _factory;
    private final Thread         _supervisor;

    public DelayedExecutor(long timeout, ThreadFactory factory) {
        _timeout = timeout;
        _factory = factory;

        _supervisor = new Thread(new Runnable() {
            @Override
            public void run() {
                while (_supervisor.isInterrupted()) {
                    try {
                        Thread.sleep(_timeout);
                    }
                    catch (InterruptedException e) {
                        if (_supervisor.isInterrupted())
                            break;
                    }

                    synchronized (_tasks) {
                        ArrayList<Runnable> prepared = new ArrayList<>(_tasks);
                        Collections.reverse(prepared);

                        execute(prepared);

                        _tasks.clear();
                    }
                }
            }
        });

        _supervisor.setDaemon(true);
        _supervisor.start();
    }

    public void schedule(Runnable runnable) {
        synchronized (_tasks) {
            _tasks.add(runnable);
        }
    }

    private void execute(final List<Runnable> tasks) {
        _factory.newThread(new Runnable() {
            @Override
            public void run() {
                for (Runnable runnable : tasks)
                    runnable.run();
            }
        });
    }
}

最佳答案

经过一些尖锐的评论后,我想我开始理解你在做什么,它看起来像是经过小修改的 Producer/Consumer 模式。根据我们的聊天,我现在了解到您希望以固定速率运行消费者!这应该会给您一个想法(但在您的实现中使用并发集合):

public FixedRateConsumer implements Runnable
{
    private final object _lock = new object();
    // *** use a concurrent collection here ***
    private Queue<Runnable> _workQueue; 

    public FixedRateConsumer()
    {
        _workQueue = new Queue<Runnable>();
    }

    public scheduleTask(Runnable task)
    {
        synchronized(_lock)
        {
            _workQueue.put(task); 
        }
    }

    public void run()
    {
        synchronized(_lock)
        {
            while(_workQueue.poll()!=null)
            {
                _workQueue.take().run();
            }
        }
    }
}

现在您只需安排消费者以固定速率运行即可:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
FixedRateConsumer consumer = new FixedRateConsumer();

scheduler.scheduleAtFixedRate(consumer, /*specify initial delay*/, /*specify rate*/, /*specify TimeUnit*/);

您的制作人可以安排这样的任务:

// Then you just schedule your tasks like this
consumer.scheduleTask(new Runnable());

关于java - 在指定的超时后从一个线程执行多个 Runnable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9180616/

相关文章:

java - 如果在 TableView JavaFx 中选择了多行,则禁用某些上下文菜单项

java - Spring Boot 验证消息未解决

java - 如何避免在使用 pdfHtml 生成的 PDF 中添加不需要的空白?

java - 如何在新添加的文本末尾自动显示插入符号到 java 中的 textArea?

java - TheApplyAsync 与 CompletableFuture 使用与 SupplyAsync 线程相同的线程

c++ - 英特尔 TBB 并行循环线程 ID

java - Java 定时器的多线程

Java - ThreadLocal 还是并发对象池?

go - “Go Concurrency Patterns: Timing out, moving on”博客中的非阻塞 channel

java - 数组的并发问题(Java)