Tattu
Tattu

Reputation: 327

NTP Server without using System time

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

Answers (2)

Christian Hujer
Christian Hujer

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:

  • The code itself that you execute between the calls to 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

SpaceTrucker
SpaceTrucker

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

Related Questions