2012-02-08 40 views
10

Tôi cần tạo dấu thời gian (tính bằng mili giây) trong Java được đảm bảo là duy nhất trong cá thể VM cụ thể đó. I E. cần một số cách để điều tiết thông lượng của System.currentTimeMillis() sao cho nó trả về nhiều nhất một kết quả mỗi ms. Bất kỳ ý tưởng về cách thực hiện điều đó?Tạo một dấu thời gian duy nhất trong Java

+2

tôi không chắc chắn những gì bạn có nghĩa là * throttling * currentTimeMillis() để nó trả về * tối đa là * một kết quả ev ery ms? Nếu bạn muốn dấu thời gian duy nhất, bạn muốn đảm bảo rằng nó trả về một giá trị khác nhau tại mỗi cuộc gọi, phải không? –

+0

Họ có phải tăng đơn điệu không? Họ có phải chịu bất kỳ mối quan hệ nào với thời gian * thực tế không? Chúng có phải là duy nhất trong nhiều lần chạy không? –

Trả lời

30

Điều này sẽ cho thời gian gần thời gian hiện tại nhất có thể mà không có bản sao.

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; 
    } 
} 

Một cách để tránh giới hạn một id mỗi milli-giây là sử dụng dấu thời gian vi giây. tức là nhân currentTimeMS vào 1000. Điều này sẽ cho phép 1000 id trên mỗi milli giây.

Lưu ý: nếu thời gian chuyển về phía sau, ví dụ như do hiệu chỉnh NTP, thời gian sẽ chỉ diễn ra ở mức 1 milli giây cho mỗi lần gọi cho đến khi thời gian bắt kịp. ;)

+0

Cảm ơn! Chính xác những gì tôi cần! – Yrlec

+0

Được sử dụng chính xác, điều này có nghĩa là bạn sẽ có id duy nhất ngay cả sau khi khởi động lại ứng dụng của mình. –

+1

Nghe hay đấy! "Sử dụng đúng" có nghĩa là chính xác hơn? – Yrlec

1

Bạn có thể sử dụng System.nanoTime(), đây là bộ hẹn giờ hệ thống có sẵn chính xác nhất và chia cho triệu để nhận mili giây. Mặc dù không có bảo đảm chính thức về mức độ thường xuyên cập nhật, tôi tin rằng nó hợp lý để giả định rằng nó cập nhật theo cách nhiều hơn (thứ tự độ lớn) thường xuyên hơn một lần mỗi mili giây. Tất nhiên, nếu bạn tạo dấu thời gian nguyên theo khoảng thời gian nhỏ hơn mili giây, thì chúng không thể là duy nhất.

Lưu ý rằng giá trị tuyệt đối nanoTime() là tùy ý. Nếu bạn muốn thời gian tuyệt đối, hãy hiệu chỉnh nó theo cách nào đó, tức là so sánh nó với currentTimeMillis() khi bắt đầu.

4

Bạn có thể sử dụng System.nanoTime() cho độ chính xác tốt hơn

Mặc dù tôi đã cố gắng bên dưới và mỗi lần nó mang lại giá trị khác nhau, nó có thể không đảm bảo là duy nhất tất cả các thời gian.

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); 
    } 

Một cách khác là sử dụng AtomicInteger/AtomicLong lớp dành cho con số duy nhất nếu thời gian không phải là quan trọng đối với bạn và bạn chỉ cần số duy nhất, điều này có lẽ là một sự lựa chọn btter.

+2

nanoTime là đơn điệu, nhưng không phải lúc nào cũng độc đáo. Bạn có thể nhận được nhiều bản sao. ví dụ. trên Red Hat & Centos 5.x độ phân giải là micro giây, vì vậy bạn nhận được rất nhiều giá trị lặp lại. –

+0

Cảm ơn thông tin. Tôi đoán nó phụ thuộc vào hệ điều hành và máy. – fmucar

+1

Bạn có thể sử dụng nanoTime với một kiểm tra khác biệt của nó. (Tương tự như giải pháp của tôi) nanoTime là thời gian hoạt động trong một giây trên nhiều hệ thống. –

1

Trong khi tìm kiếm một giải pháp tôi đi qua ULIB (Universally Unique thứ tự từ điển Sortable định danh) https://github.com/huxi/sulky/tree/master/sulky-ulid/

Nó không phải là dài, nhưng ngắn hơn sau đó UUID.

Một ULID:

  • là tương thích với UUID/GUID của 1.21E + 24 ULIDs độc đáo mỗi millisecond (1,208,925,819,614,629,174,706,176 để được chính xác)
  • thứ tự từ điển sắp xếp được
  • theo giáo luật mã hóa như là một chuỗi 26 nhân vật, như trái ngược với UUID 36 nhân vật
  • Sử dụng base32 Crockford cho hiệu quả tốt hơn và dễ đọc (5 bit mỗi nhân vật)
  • Trường hợp không nhạy cảm
  • không ký tự đặc biệt (URL an toàn)
Các vấn đề liên quan