2012-01-28 30 views
17

जावा टाइमर का उपयोग कर रहा था, फिर शेड्यूल किए गए एक्सप्लोरर सेवा पर स्विच किया गया, लेकिन मेरी समस्या ठीक नहीं है। सिस्टम समय परिवर्तन (एनटीपीडी के माध्यम से) निर्धारित किए गए कार्यों को निर्दिष्ट विलंब पर निष्पादित नहीं किया जाता है। 64 बिट लिनक्स पर अपने लक्षित में JRE 1.6.0_26 64 बिट का उपयोग कर कुछ भी नहीं :(होता है के रूप में ही की कोई लॉग हैजावा शेड्यूलर जो सिस्टम समय परिवर्तनों से पूरी तरह से स्वतंत्र है

अद्यतन:।।। ScheduledExecutorService विंडोज पर ठीक काम करता है समस्या केवल पर है 64 बिट लिनक्स आधारित प्रणाली 64 बिट JVM चल रहा है। यह 64 बिट 32 बिट JVM ... अजीब। चल लिनक्स पर ठीक काम करता है नहीं या तो किसी भी ब्लॉग पर एक ही के किसी भी संदर्भ मिल गया है।

आईबीएम के जावा एसडीके एक ही समस्या है (ibm-java-sdk-7.0-0.0-x86_64-archive.bin)

मैं JDK 7139684 के खिलाफ दोष दायर किया था, यह स्वीकार कर लिया गया है, लेकिन बंद कर दिया गया और 6900441 की डुप्लीकेट चिह्नित। यह उसके लिए वोट करें, यदि आप इसके लायक हो तय करने के लिए लग रहा है ... मुझे पता नहीं क्यों अपने साल की जोड़ी की तुलना में अधिक के बाद से तय नहीं किया गया है

यहाँ नमूना कोड मैं इस मुद्दे का परीक्षण करने के लिए प्रयोग किया जाता है :

package test; 

import java.io.IOException; 
import java.util.Date; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

/** 
* @author yogesh 
* 
*/ 
public class TimerCheck implements Runnable { 

    ScheduledExecutorService worker; 


    public TimerCheck(ScheduledExecutorService worker) { 
     super(); 
     this.worker = worker; 
     this.worker.schedule(this, 1, TimeUnit.SECONDS); 
    } 

    private static void update() { 
     System.out.println("TimerCheck.update() "+new Date(System.currentTimeMillis())); 
    } 

    @Override 
    public void run() { 
      update(); 
      worker.schedule(this, 1, TimeUnit.SECONDS); 
    } 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     ScheduledExecutorService worker = Executors.newScheduledThreadPool(1); 
     new TimerCheck(worker); 
    } 

} 
+1

यह नमूना कोड मेरी मशीन ubuntu पर ठीक चलाता 11.10 [32 बिट], JVM 1.6.0_21 [32 बिट]। सिस्टम घड़ी बदलना निष्पादन को प्रभावित नहीं करता है। – Gopi

+0

हाँ यह भी जांचता है कि 32 बिट जेवीएम चलने वाले 64 बिट लिनक्स पर ठीक चल रहा है :(। मेरे प्रश्न को तदनुसार अपडेट किया गया। – YoK

+1

मैं यह इंगित करना चाहता हूं कि इस मामले में नैनोसेकंड निर्दिष्ट करना अर्थहीन है। आंतरिक रूप से, कोड भी मिलिस में बदल जाता है। तो 'worker.schedule (यह, 1000000000, TimeUnit.NANOSECONDS);' वर्कर्स.schedule (यह, 1, TimeUnit.SECONDS) के समान है; ' –

उत्तर

7

साइटेम समय के दौरान समग्र शेड्यूलिंग के लिए bug in JVM है, जो भी बहुत मूल ऑब्जेक्ट को प्रभावित करता है। Wait & Thread.sleep विधियां। जावा ऐप को चलाना बहुत जोखिम भरा हो जाता है जब सिस्टम समय कुछ सेकंड तक वापस स्विच करता है। आप कभी नहीं जानते कि आपका जावा ऐप क्या खत्म हो जाएगा। समय परिवर्तन की जाँच करने के

  • लिखें घड़ी कुत्ता लिपि (गैर जावा :)):

    तो हम का फैसला किया है।

  • यदि समय कुछ निश्चित राशि से वापस स्विच करता है, तो बंद करें और जावा ऐप को पुनरारंभ करें।

32 बिट जेवीएम में जाने की एक और संभावना थी, लेकिन हम जेएनआई का उपयोग कर रहे हैं और फिर लक्षित प्लेटफ़ॉर्म पर उपयोग की जाने वाली मूल पुस्तकालय 32 बिट संगत नहीं हैं। हमारे अनुभव से 32 बिट जेवीएम हमारे लक्ष्य को 1.6 जी ढेर तक सीमित कर देता है, जो हमारे लिए पर्याप्त नहीं है।

मुझे पता है कि हमारा सबसे सुंदर समाधान नहीं है, लेकिन जब तक जेवीएम तय नहीं होता है या कुछ बेहतर समाधान मिलता है, तो ऐसा कोई अन्य तरीका नहीं लगता है।

संपादित: भी हम उपरोक्त समाधान के अलावा क्रिस से 1 सुझाव पर विचार कर रहे:

  • कॉन्फ़िगर एनटीपी एक बड़ा समय कूद की आवश्यकता नहीं है करने के लिए। केवल धीरे-धीरे समय को मार डाला। डाउनटाइम के दौरान मैन्युअल रूप से बड़े समय पर कूदें।
+0

इस उत्तर को वर्कअराउंड के रूप में स्वीकार करते हुए :(। अभी भी उचित समाधान की प्रतीक्षा करते समय। – YoK

+0

मुझे समझ में नहीं आता है, यह जेवीएम को कितना गहराई से प्रभावित करता है। आपके एवर से ऐसा लगता है कि यह महत्वपूर्ण बग है। उदाहरण के लिए, यदि मैं ऑब्जेक्ट.वाइट (1) का उपयोग करता हूं, और घड़ियों को वापस ले जाया जाता है - क्या इसका मतलब है कि धागा कभी नहीं जगाया जा सकता है? – BegemoT

+0

@ बेगमो इसका मतलब यह नहीं है कि यह कभी नहीं जाग जाएगा ...लेकिन इसके बाद जाग जाएगा (टाइम घड़ी वापस ले जाया गया है + 1)। जो खतरनाक है। और यह 64 बिट लिनक्स पर केवल 64 बिट जेवीएम पर हो रहा है। – YoK

2

मैं एक ही समस्या के खिलाफ काम किया है और एक समाधान नहीं मिला है। मैंने क्वार्ट्ज और सभी अंतर्निर्मित जेआरई तरीकों को देखा। नैनोटाइम विधियां प्रति-सीपीयू मोनोटोनिक घड़ियों का उपयोग कर सकती हैं, लेकिन अगर थ्रेड को किसी दूसरे सीपीयू में माइग्रेट किया जाता है, तो आप बड़े कूदते हैं, मुझे विश्वास है। मेरे निष्कर्ष निम्नलिखित थे:

  1. एनटीपी को कभी भी बड़ा समय कूदने के लिए कॉन्फ़िगर करें। केवल धीरे धीरे समय मारा। डाउनटाइम के दौरान मैन्युअल रूप से बड़े समय पर कूदें।
  2. एकाधिक छोटे टाइमआउट का उपयोग करें, और रिमोट मशीन मृत घोषित करने के लिए दो टाइमआउट की आवश्यकता है। इससे आपकी मदद नहीं होगी यदि आपके पास केवल एक सिस्टम समय है, लेकिन कई सिस्टम
  3. आपको समय-समय पर जागरूकता भेजने के उद्देश्य से रिमोट मशीन का उपयोग करने में सहायता कर सकता है। यदि आपकी घड़ी घड़ी के बीच पिछड़ी हो जाती है, तो आप जानते हैं कि आपके सभी टाइमर देर से आग लगेंगे।

असल में, यह एक बड़ा दर्द है लेकिन चांदी की गोलियाँ नहीं हैं।

+0

लेकिन क्या आपने अंततः इन समाधानों में से कोई भी आवेदन किया था। मेरे लिए ये असंभव हैं :) – YoK

+2

@YoK, हाँ सब तीन। मेरा परिदृश्य यह पता लगा रहा था कि प्राथमिक सेवा की मृत्यु कब हुई थी, इसलिए बैकअप स्वचालित रूप से खत्म हो सकता था। एनटीपी कॉन्फ़िगरेशन में मैंने सभी व्यवहारों का उपयोग किया है: यदि सिंक एन मिनट के भीतर है (2 कहें) तो धीरे-धीरे एक्स मिल प्रति मिनट (20 कहें) की दर से सही समय की घड़ी को धीरे-धीरे मार दें। यदि सिंक एन मिनट से अधिक है, तो एनटीपी त्रुटि के सिस्टम लॉग संदेश चेतावनी जारी करता है और निष्क्रिय हो जाता है। –

+0

दिलचस्प ... मेरे एनटीपी लोगों से यह देखने के लिए कहेंगे। – YoK