[英]Thread.sleep() VS Executor.scheduleWithFixedDelay()
[英]Executor Service and scheduleWithFixedDelay()
這是我的任務。 我在一個類中有一個靜態的作業隊列,還有一個將作業添加到隊列的靜態方法。 有n個線程從隊列中輪詢並執行拉出的作業。 我需要讓n個線程同時進行輪詢。 又說,這3個人應每5秒輪詢一次並尋找工作。
我有這個:
public class Handler {
private static final Queue<Job> queue = new LinkedList<>();
public static void initialize(int maxThreads) { // maxThreads == 3
ScheduledExecutorService executorService =
Executors.newScheduledThreadPool(maxThreads);
executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
Job job = null;
synchronized(queue) {
if(queue.size() > 0) {
job = queue.poll();
}
}
if(job != null) {
Log.log("start job");
doJob(job);
Log.log("end job");
}
}
}, 15, 5, TimeUnit.SECONDS);
}
}
當我添加4個任務時,我得到以下輸出:
startjob
endjob
startjob
endjob
startjob
endjob
startjob
endjob
顯然,這些線程按順序執行該作業,而我需要一次完成3個。 我究竟做錯了什么? 謝謝!
從文檔中:
如果此任務的任何執行花費的時間超過其周期,則后續執行可能會開始得較晚,但不會同時執行。
因此,您必須安排三個獨立的任務以使其同時運行。 還要注意,計划執行程序服務是固定線程池,對於許多用例而言,它不夠靈活。 一個好的習慣用法是使用計划服務,只是將任務提交給常規執行程序服務,該服務可以配置為可調整大小的線程池。
您正在以固定的延遲運行ScheduledExecutorService
,這意味着您的作業將一個接一個地運行。 使用固定線程池,並一次提交3個線程。 這是帶有示例的說明
如果聲明Job extends Runnable
那么您的代碼將大大簡化:
首先,在全球可訪問的地方聲明執行器:
public static final ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
然后添加如下工作:
executor.submit(new Job());
大功告成
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.