java - 在周期性运行的线程中自发执行代码

标签 java multithreading

我有一个定期执行代码的线程,e。 G。每 10 秒。我希望可以选择以自发的方式调用相同的代码,而不必等待 10 秒。但是自动和自发执行的代码绝不能并发运行,如果用户在线程调用相同方法时按下执行按钮,它们应该顺序运行。

有没有人知道可以满足这种要求的好的模式或类?

首先想到的是使工作方法同步。但在那种情况下,手动执行(例如按下按钮)会被阻塞,必须等到线程中的方法完成。有没有更好的不阻塞的方法?

例子:

public class Executor extends Thread {

    // endless loop, executes work method periodically with pause inbetween
    @Override
    public void run() {

        while( true) {

            work( "automatic");

            pause(10000);

        }

    }

    // Working method that's executed periodically or manually
    private synchronized void work( String text) {

        System.out.println( "Working " + text + " " + System.currentTimeMillis());

    }

    // helper method that pauses the thread
    private static void pause( long sleepMs) {
        try {

            Thread.sleep(sleepMs);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        // start automatic execution
        Executor executor = new Executor();
        executor.start();

        // pause a while
        pause(1000);

        // manual execution
        executor.work( "manual");

    }

}

编辑:满足我的要求的解决方案:

public class ScheduledExecutor {

    public static void main(String[] args) throws InterruptedException {

        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
        executor.scheduleWithFixedDelay(new Work("auto"), 0, 10, TimeUnit.SECONDS);

        Thread.sleep(1000);

        executor.execute(new Work("manual"));

    }

    public static class Work implements Runnable {

        String text;

        public Work(String text) {
            this.text = text;
        }

        @Override
        public void run() {

            System.out.println("Working " + text + " " + System.currentTimeMillis());

        }
    }

}

最佳答案

我会创建一个新的单线程执行器服务:

ExecutorService executorService = Executors.newFixedThreadPool(1);

然后,我会设置一个计时器,每 10 秒向 executorService 提供一个任务。

new Timer(10000, new ActionListener {
    public void actionPerformed(ActionEvent evt) {
        executorService.execute(() -> doWhatever());
    }
}).start();

最后,您可以在按钮按下处理程序中或代码中的任何其他地方调用 executorService.execute(() -> doWhatever());

一次只会运行一个 doWhatever() 激活,因为 executorService 只有一个线程可以运行它们。而且,您的按钮按下处理程序将永远不必等待,因为它除了将新对象放入队列外什么都不做。

关于java - 在周期性运行的线程中自发执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44246575/

相关文章:

java - MVC模式中Main类的位置和职责

Java多线程执行超出循环范围

php - 在屏幕上向用户使用php显示页面时,在后台执行shell脚本

java - 强制 JPA 查询急切地返回所有集合/字段

java - Java动态连接数据库(Spring Boot)

java - 这个标准化功能如何工作?

c++ - 从许多其他线程中触发一个线程

Java IBM MQ 客户端已连接但未从队列获取消息

c++ - 在 C++ 中构建多线程工作队列(消费者/生产者)

java - 当CPU非常繁忙时,我的多线程java程序出现意外异常