为了账号安全,请及时绑定邮箱和手机立即绑定

Java 线程执行受计数和时间限制

Java 线程执行受计数和时间限制

侃侃无极 2022-06-30 11:44:22
我有进程列表,我想像每分钟十个进程一样执行它们。我试过了ExecutorService,但没有一个能支持我的情况,我也试过了,ThreadPoolExecutor但也许我无法弄清楚如何正确实现它。RateLimiterRxJava例子我有Runnable大小为100K的列表,每个Runnable都有这个逻辑:从 检索数据rest api。对数据进行一些计算。将结果保存在数据库中。所以我使用ExecutorService大小10并在内部设置延迟(5 秒)Runnable#run()来管理我需要的“每分钟十个进程”,但仍然无法管理。这个逻辑的要点是减少对rest api.更新实际上,我们正在寻找的是有一个上限(在时间和操作数方面),而不是在各个操作之间平均分配时间,而不管它们各自的吞吐量如何。即,如果我有一个包含 100 个操作的列表,每个操作需要 0.5 秒,并且我有一个速率限制器,而不是(分发后)确定单个操作应该花费 0.8 秒,那么我可以使用 0.3 秒的间隙来启动一个新的操作
查看完整描述

3 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

我认为使用 a 并以固定速率安排 a 将获得最佳java.util.Timer结果。TimerTask


假设您有一个TimerTask在执行时打印出日期的。


public class PrintTimeAndIdTask extends TimerTask {


    private int id;


    public PrintTimeAndIdTask(int id) {

        this.id = id;

    }


    public void run() {

        System.out.println(new Date() + " : " + id);

    }

}

然后创建一个计时器并安排任务。每个都有不同的延迟,以便它们在您的首选时间间隔内平均分布。


public static void main(String[] args) {

    Timer timer = new Timer();


    int taskCount = 10;

    int timeIntervalMs = 60000;

    int delayBetweenTasks = timeIntervalMs / taskCount;



    for (int i = 0; i < taskCount; i++) {

        TimerTask timerTask = new PrintTimeAndIdTask(taskCount);


        int taskDelay = (long) taskCount * delayBetweenTasks;


        timer.scheduleAtFixedRate(timerTask, taskDelay, timeIntervalMs);

    }

}

您会看到每 6 秒执行一次任务。


Wed Feb 20 17:17:37 CET 2019 : 0

Wed Feb 20 17:17:43 CET 2019 : 1

Wed Feb 20 17:17:49 CET 2019 : 2

Wed Feb 20 17:17:55 CET 2019 : 3

Wed Feb 20 17:18:01 CET 2019 : 4

Wed Feb 20 17:18:07 CET 2019 : 5

Wed Feb 20 17:18:13 CET 2019 : 6

Wed Feb 20 17:18:19 CET 2019 : 7

Wed Feb 20 17:18:25 CET 2019 : 8

Wed Feb 20 17:18:31 CET 2019 : 9

Wed Feb 20 17:18:37 CET 2019 : 0

Wed Feb 20 17:18:43 CET 2019 : 1

Wed Feb 20 17:18:49 CET 2019 : 2

Wed Feb 20 17:18:55 CET 2019 : 3

....

请记住,Timer默认情况下 a 不作为守护线程运行。如果您没有在应用程序关闭时明确取消它,它会继续运行,因此您的应用程序将不会关闭。


查看完整回答
反对 回复 2022-06-30
?
猛跑小猪

TA贡献1858条经验 获得超8个赞

我可能会从延迟队列中提供我的线程池,将自己限制为每分钟 10 个。

有关如何BlockingQueue.


查看完整回答
反对 回复 2022-06-30
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

你的意思是这样吗?产生一个线程的单个执行程序,该线程本身产生 10 个线程。


private static final int numProcesses = 10;

private static final ExecutorService executorService = Executors.newFixedThreadPool(numProcesses);


public static void main(String[] args)

{

    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    executorService.scheduleAtFixedRate(Test::spawnTenThreads, 0, 5, TimeUnit.SECONDS);

}


private static void spawnTenThreads()

{

    for (int i = 0; i < numProcesses; ++i)

    {

        final int iteration = i;

        executorService.submit(() -> System.out.println(iteration));

    }

}


查看完整回答
反对 回复 2022-06-30
  • 3 回答
  • 0 关注
  • 284 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号