ตั้งแต่ Java 7 System.nanoTime()
รับประกันว่าปลอดภัยด้วยข้อกำหนดของ JDK System.nanoTime()
Javadoc ของทำให้ชัดเจนว่าการเรียกใช้ทั้งหมดที่ตรวจพบภายใน JVM (นั่นคือข้ามเธรดทั้งหมด) เป็นแบบโมโนโทน:
ค่าที่ส่งคืนแสดงถึง nanoseconds ตั้งแต่บางเวลาคงที่ แต่กำเนิดโดยพลการ (อาจเป็นในอนาคตดังนั้นค่าอาจเป็นค่าลบ) ต้นกำเนิดเดียวกันถูกใช้โดยการเรียกใช้เมธอดนี้ทั้งหมดในอินสแตนซ์ของเครื่องเสมือน Java อินสแตนซ์ของเครื่องเสมือนอื่น ๆ มีแนวโน้มที่จะใช้ต้นกำเนิดที่แตกต่างกัน
การดำเนินการ JVM / JDK มีหน้าที่รับผิดชอบในการขจัดความไม่สอดคล้องที่อาจสังเกตได้เมื่อเรียกยูทิลิตี้ระบบปฏิบัติการพื้นฐาน (เช่นที่กล่าวถึงในคำตอบของ Tom Anderson )
ส่วนใหญ่ของคำตอบเก่าอื่น ๆ สำหรับคำถามนี้ (เขียนใน 2009-2012) แสดง FUD ที่อาจเกี่ยวข้องกับ Java 5 หรือ Java 6 แต่ไม่เกี่ยวข้องกับ Java รุ่นที่ทันสมัยอีกต่อไป
อย่างไรก็ตามมันมีค่าที่จะกล่าวถึงแม้ว่าจะรับประกันnanoTime()
ความปลอดภัยของJDK แต่ก็มีข้อบกพร่องหลายอย่างใน OpenJDK ที่ทำให้ไม่สนับสนุนการรับประกันนี้ในบางแพลตฟอร์มหรือในบางสถานการณ์ (เช่นJDK-8040140 , JDK-8184271 ) ไม่มีข้อผิดพลาดที่เปิด (open) ใน OpenJDK wrt nanoTime()
ในขณะนี้ แต่การค้นพบข้อผิดพลาดดังกล่าวใหม่หรือการถดถอยในการเปิดตัว OpenJDK รุ่นใหม่ไม่ควรทำให้ใครตกใจ
โดยที่ในใจรหัสที่ใช้nanoTime()
สำหรับการบล็อกที่กำหนดเวลาการรอช่วงเวลาการหมดเวลา ฯลฯ ควรปฏิบัติต่อความแตกต่างของเวลาเชิงลบ (timeouts) เป็นศูนย์แทนที่จะเป็นโยนข้อยกเว้น การปฏิบัตินี้ยังเป็นที่นิยมเพราะมันมีความสอดคล้องกับพฤติกรรมของทุกวิธีการรอเวลาที่กำหนดในทุกชั้นในjava.util.concurrent.*
เช่นSemaphore.tryAcquire()
, Lock.tryLock()
,BlockingQueue.poll()
ฯลฯ
อย่างไรก็ตามnanoTime()
ยังควรใช้การบล็อกที่กำหนดเวลาการรอช่วงเวลาการหมดเวลาและอื่น ๆcurrentTimeMillis()
เนื่องจากสิ่งหลังเป็นเรื่องของปรากฏการณ์ "เวลาย้อนหลัง" (เช่นเนื่องจากการแก้ไขเวลาของเซิร์ฟเวอร์) เช่นcurrentTimeMillis()
ไม่เหมาะสำหรับการวัดช่วงเวลา เลย ดูคำตอบนี้สำหรับข้อมูลเพิ่มเติม
แทนการใช้nanoTime()
สำหรับการวัดเวลาโค้ดโดยตรงเฉพาะการเปรียบเทียบกรอบและโปรควรนำมาใช้เช่นJMHและasync-Profilerในโหมดผนังนาฬิกาโปรไฟล์