2012-02-08 20 views
10

में एक अनूठा टाइमस्टैम्प बनाना मुझे जावा में एक टाइमस्टैम्प (मिलीसेकंड में) बनाने की आवश्यकता है जो उस विशेष वीएम-इंस्टेंस में अद्वितीय होने की गारंटी है। अर्थात। System.currentTimeMillis() के थ्रूपुट को थ्रॉटल करने के लिए किसी भी तरीके की आवश्यकता है ताकि यह प्रत्येक एमएस के अधिकांश परिणामों पर लौट सके। इसे लागू करने के तरीके पर कोई विचार?जावा

+2

मुझे यकीन है कि नहीं कर रहा हूँ तुम्हारा क्या मतलब है * थ्रॉटलिंग * currentTimeMillis() इतना है कि यह देता है * सबसे * एक परिणाम EV पर ery एमएस? यदि आप अद्वितीय टाइमस्टैम्प चाहते हैं, तो आप यह गारंटी देना चाहते हैं कि यह प्रत्येक कॉल पर एक अलग मूल्य देता है, है ना? –

+0

क्या उन्हें एकान्त रूप से बढ़ना होगा? क्या उन्हें वास्तविक * समय * के साथ कोई संबंध रखना है? क्या उन्हें कई रनों में अद्वितीय होना चाहिए? –

उत्तर

30

यह डुप्लीकेट के बिना जितना संभव हो सके वर्तमान समय को बंद कर देगा।

private static final AtomicLong LAST_TIME_MS = new AtomicLong(); 
public static long uniqueCurrentTimeMS() { 
    long now = System.currentTimeMillis(); 
    while(true) { 
     long lastTime = LAST_TIME_MS.get(); 
     if (lastTime >= now) 
      now = lastTime+1; 
     if (LAST_TIME_MS.compareAndSet(lastTime, now)) 
      return now; 
    } 
} 

एक आईडी प्रति मिली-सेकंड की सीमा से बचने का एक तरीका माइक्रो-सेकंड टाइमस्टैम्प का उपयोग करना है। यानी 1000 से वर्तमान टाइम्स को गुणा करें। यह 1000 ids प्रति मिली-सेकंड की अनुमति देगा।

नोट: यदि समय पीछे की ओर जाता है, उदाहरण के लिए एनटीपी सुधार के कारण, समय केवल 1 मिली-सेकेंड प्रति आमंत्रण पर प्रगति करेगा जब तक कि समय पकड़ न जाए। ;)

+0

धन्यवाद! वास्तव में मुझे क्या चाहिए! – Yrlec

+0

सही ढंग से प्रयुक्त होता है, इसका मतलब यह होगा कि आपके एप्लिकेशन को पुनरारंभ करने के बाद भी आपके पास अद्वितीय आईडी होंगे। –

+1

अच्छा लगता है! "सही ढंग से इस्तेमाल किया" का अर्थ क्या अधिक सटीक है? – Yrlec

1

आप System.nanoTime() का उपयोग कर सकते हैं, जो कि सबसे सटीक उपलब्ध सिस्टम टाइमर है, और मिलीसेकंड प्राप्त करने के लिए लाखों तक विभाजित करें। हालांकि यह कितनी बार अद्यतन किया जाता है इस पर कोई औपचारिक गारंटी नहीं है, मेरा मानना ​​है कि यह मानना ​​उचित है कि यह प्रति मिलीसेकंड से एक बार से अधिक बार (परिमाण का क्रम) अद्यतन करता है। बेशक, यदि आप मिलीसेकंद अंतराल से कम द्वारा पूर्णांक टाइमस्टैम्प बनाते हैं, तो वे सभी अद्वितीय नहीं हो सकते हैं।

ध्यान दें कि पूर्ण मान nanoTime() मनमाने ढंग से है। यदि आप पूर्ण समय चाहते हैं, तो इसे किसी भी तरह से कैलिब्रेट करें, यानी इसे शुरू करते समय currentTimeMillis() पर तुलना करें।

4

आप हालांकि मैं नीचे की कोशिश की बेहतर सटीकता

के लिए System.nanoTime() उपयोग कर सकते हैं और हर बार यह अलग-अलग मान देता है, यह शायद हर समय अद्वितीय होने की गारंटी नहीं है।

public static void main(String[] args) { 
     long time1 = System.nanoTime(); 
     long time2 = System.nanoTime(); 
     long time3 = System.nanoTime(); 
     System.out.println(time1); 
     System.out.println(time2); 
     System.out.println(time3); 
    } 

एक और तरीका है, अगर समय आप के लिए महत्वपूर्ण नहीं है और तुम सिर्फ अद्वितीय संख्या की जरूरत है अद्वितीय संख्या के लिए AtomicInteger/AtomicLong वर्गों का उपयोग करने के लिए है यह शायद एक btter विकल्प है।

+2

नैनोटाइम monotonic है, लेकिन हमेशा अद्वितीय नहीं है। आप बहुत सारे डुप्लिकेट प्राप्त कर सकते हैं। जैसे Red Hat और Centos 5.x पर संकल्प माइक्रो-सेकेंड है, इसलिए आपको कई बार दोहराए गए मान मिलते हैं। –

+0

जानकारी के लिए धन्यवाद। मैंने अनुमान लगाया कि यह ओएस और मशीन पर निर्भर करता है। – fmucar

+1

आप एक चेक के साथ नैनोटाइम का उपयोग कर सकते हैं कि यह अलग है। (मेरे समाधान के समान) नैनोटाइम कई प्रणालियों पर एनो-सेकेंड में अपटाइम है। –

0

क्या आप शायद java.util.UUID का उपयोग कर सकते हैं और यह timestamp() और clockSequence() है?

Method Summary 
    int clockSequence() 
     The clock sequence value associated with this UUID. 
    long timestamp() 
     The timestamp value associated with this UUID. 

अधिक यहाँ विवरण: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html

1

जबकि एक समाधान मैं ULIBमें आए (वैश्विक अनुपम कोषगत क्रमित करने योग्य पहचानकर्ता) https://github.com/huxi/sulky/tree/master/sulky-ulid/

यह नहीं कर रहा है एक लंबे समय के लिए खोज, लेकिन छोटे फिर यूयूआईडी।

एक ULID:

  • UUID के साथ संगत है/GUID के 1।मिलीसेकंड प्रति 21E + 24 अद्वितीय ULIDs (1,208,925,819,614,629,174,706,176 सटीक होना करने के लिए)
  • कोषगत sortable
  • के रूप में 36 चरित्र UUID
  • बेहतर दक्षता और पठनीयता के लिए Crockford के base32 का उपयोग करता है करने का विरोध किया धर्मविधान, एक 26 चरित्र स्ट्रिंग के रूप में एन्कोड (5 बिट्स प्रति चरित्र)
  • मामले असंवेदनशील
  • कोई विशेष वर्ण (सुरक्षित यूआरएल)