जावा अनुसूचित अधिकारियों का उपयोग करते समय मुझे एक विशिष्टता मिली और मुझे आश्चर्य हुआ कि मैंने जो अनुभव किया वह सामान्य है।जावा अनुसूचित निष्पादक सटीकता
मुझे उन कार्यों को शेड्यूल करने की आवश्यकता है जो 5 सेकंड की पूर्वनिर्धारित दर पर निष्पादित हों। यह अपेक्षा की जाती है कि इन कार्यों को समय-समय पर निष्पादित करने में 5 सेकंड से अधिक समय लगेगा, लेकिन जब उन्हें चलाने का समय 5 सेकंड से नीचे चला जाता है, तो कार्यों की बैक अप सूची को पकड़ने के लिए त्वरित उत्तराधिकार में चलना चाहिए। कार्यों को चलाने के दौरान, यह जानना महत्वपूर्ण है कि मूल अनुसूचित निष्पादन समय क्या था (scheduledExecutionTime()
java.util.TimerTask
में सोचें)। आखिरकार, अनुसूची समय और वास्तविक समय के बीच अंतर को ट्रैक करने की आवश्यकता है ताकि यह निर्धारित किया जा सके कि शेड्यूल "बहती" कब और कितनी है।
अब तक मैं जावा निष्पादकों का उपयोग करके इस सब को लागू किया है, और निम्न वर्ग सामान्य विचार दिखाता है:
public class ExecutorTest {
public static final long PERIOD = 5000;
public static void main(String[] args) {
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Command(), 0, PERIOD, TimeUnit.MILLISECONDS);
}
private static final class Command implements Runnable {
long timestamp = 0;
public void run() {
long now = System.currentTimeMillis();
if (timestamp == 0) {
timestamp = now;
}
// Drift is the difference between scheduled time and execution time
long drift = now - timestamp;
String format = "Ran at %1$tF %<tT,%<tL; drift: %2$dms";
System.out.println(String.format(format, now, drift));
timestamp += PERIOD;
}
}
}
ऊपर सूचीबद्ध कोड चल रहा है पता चलता है कि बहाव (जो आदर्श के नजदीक होना चाहिए 0 जितना संभव हो) कुछ सेकंड तक उतार-चढ़ाव करता है, जिसके परिणामस्वरूप कार्य समय-समय पर या देर से निष्पादित होते हैं। मैं लगभग 150 मिनट के लिए इस चलाने के परिणामों से एक ग्राफ बनाया है:
तो मेरा पहला सवाल यह है कि यह सामान्य है है। मेरे पर्यावरण में 32 बिट विंडोज एक्सपी और जावा 1.5 अपडेट 21 शामिल हैं (हालांकि जावा 6 अपडेट 22 इसी तरह के परिणाम उत्पन्न करता है)।
दूसरा सवाल यह है कि बहाव की मात्रा को कम करने का एक आसान तरीका है या नहीं। यदि मैं एक साधारण java.util.Timer
या यहां तक कि केवल Thread.sleep()
का उपयोग करता हूं, तो बहाव अस्तित्व में नहीं है।
आखिरकार, नियत निष्पादकों का उपयोग करते समय निर्धारित निष्पादन समय को ट्रैक करने का एक बेहतर तरीका है?