Reputation: 327
I have a desktop PC with no internet connection or GPS receiver. I need to build an NTP server application, preferably in JAVA, without using system time.
I have used the following method.
public void run()
{
Date oDate = new Date();
time = oDate.getTime();
System.out.println("Syst Time--->"+oDateFormat.format(time));
while(true)
{
try
{
Thread.sleep(100);
time = time+100;
oDate = new Date();
if(time % 11443 == 1)
{
System.out.println("Time--->"+oDateFormat.format(time)+" Syst Time--->"+oDateFormat.format(oDate));
oDate = null;
}
}
catch (InterruptedException ex)
{
Logger.getLogger(NTPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
What I am doing is there is a thread which sleeps for 100 milliseconds and after that I add 100 to the time variable which keeps my time. But it creates a 2-3 second difference with the system time every time its printed. Basically its not accurate.
Is there any other way?
Upvotes: 0
Views: 410
Reputation: 17975
Using Thread.sleep(100);
will not ensure that your loop is executed precisely every 100ms. There are at least two things to consider:
Thread.sleep(100)
takes time to execute.Thread.sleep(100)
does not sleep exactly 100ms, but it sleeps at least 100ms. When your program really continues after Thread.sleep()
is undefined and depends on implementation-defined aspects like the VM scheduler and the OS scheduler.Time cannot be measured by software in environments with non-deterministic timing behavior. Non-deterministic timing behavior is caused by schedulers, caches, multitasking, multi-threading, hard disks etc..
You'll have to rely on system time, using System.currentTimeMillis()
and System.nanoTime()
.
Upvotes: 2
Reputation: 13556
You can use System.nanoTime()
as per documentation:
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.
So you won't violate youre requirement in using system time. Then you basically need to do the following:
long before = System.nanoTime();
Thread.sleep(100);
long after = System.nanoTime();
time = time+((after-before)/1000000L);
You production code should be aware of overflows that might happen to nanoTime during sleep.
Upvotes: 0