以下示例顯示了ScheduledExecutorService中的問題。我正在計劃兩個運行時間比計劃時間間隔長的任務「1」和「2」。任務「2」提交另一個任務只執行一次。ScheduledExecutorService中的公平性問題
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TestExecutorFairness {
public static void main(final String[] args) {
final int interval = 200;
final int sleeptime = 600;
final ScheduledExecutorService executor = Executors
.newSingleThreadScheduledExecutor();
// schedule task 1
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(sleeptime);
} catch (final InterruptedException e) {
e.printStackTrace();
}
System.out.println("1");
}
}, interval, interval, TimeUnit.MILLISECONDS);
// schedule task 2
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(sleeptime);
} catch (final InterruptedException e) {
e.printStackTrace();
}
System.out.println("2");
// submit task 3
executor.submit(new Runnable() {
@Override
public void run() {
System.out.println("3");
}
});
}
}, interval, interval, TimeUnit.MILLISECONDS);
}
}
我所期望的輸出是一樣的東西
1
2
1
2
3
但不執行的方式。任務「3」延遲很長,但我需要儘快執行它。
有什麼方法可以將此行爲更改爲更公平嗎?或者有人有更好的解決方案?
我也考慮過更多的線程,但'Thread.sleep()'是Modbus TCP通信的佔位符。這個庫不是爲多線程而設計的。我也可以分成一個執行者和一個執行者,但是如果任務花費太長時間,那麼這個隊列就會佔用執行者的隊列。 – Stephan
因此,有2個週期性任務可能需要比調度時間間隔更長的時間,並且它們阻止當前線程 - 我無法想象在這種情況下應該如何立即執行第三個任務*。根據當前的描述,我現在看到的唯一解決方案是不安排任務3,但直接在任務2中直接執行相應的「Runnable」 - 但由於這太明顯了,我認爲有一個原因你沒有這樣做...... – Marco13
我在任務2中執行任務3只是爲了模擬以後的調用。但我想直接提交比計劃任務更高的優先級。 – Stephan