簡體   English   中英

Java線程執行受計數和時間限制

[英]Java thread execution limited by count and time

我有進程列表,我想像每分鍾執行十個進程那樣執行它們。

我嘗試了ExecutorServiceThreadPoolExecutorRateLimiter但是它們都不支持我的情況,我也嘗試了RxJava但也許我不知道如何正確實現它。


我有大小為100KRunnable列表,每個Runnable具有以下邏輯:

  • rest api檢索數據。
  • 對數據進行一些計算。
  • 將結果保存在數據庫中。

因此,我使用大小為10的 ExecutorService並在Runnable#run() 內設置Delay(5秒)來管理我需要的“每分鍾十個進程” ,但仍然無法管理。

該邏輯的要點是減少對rest api請求。


更新

有效地,我們正在尋找的是有一個上限(時間和操作數),而不是將時間均勻地分配給各個操作,而不管它們的吞吐量如何。

例如,如果我有一個100個操作的列表,每個操作將花費0.5秒,並且我有一個速率限制器,該速率限制器比(分配后)確定單個操作應花費0.8秒,那么我可以使用0.3秒的間隔來啟動一個新操作

我可能會從DelayQueue喂我的threadPool,以將自己限制為每分鍾10個。

有關如何從BlockingQueue饋給執行程序的示例,請參見https://stackoverflow.com/a/6306244/823393

你的意思是這樣嗎? 產生線程的單個執行程序本身會產生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));
    }
}

我認為您可以使用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不會作為守護程序線程運行。 如果您沒有在應用程序關閉時明確取消它,則它將保持運行狀態,因此您的應用程序將不會關閉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM