Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 G53SRP: Clocks and Time in Java Chris Greenhalgh School of Computer Science.

Similar presentations


Presentation on theme: "1 G53SRP: Clocks and Time in Java Chris Greenhalgh School of Computer Science."— Presentation transcript:

1 1 G53SRP: Clocks and Time in Java Chris Greenhalgh School of Computer Science

2 2 Contents The system clockThe system clock SleepingSleeping Absolute delaysAbsolute delays Time-outs on waitTime-outs on wait Java 1.5 extensions: TimeUnit, nanoTimeJava 1.5 extensions: TimeUnit, nanoTime Events, Timers and TimerTasksEvents, Timers and TimerTasks Book: Wellings 4.2 & 4.4Book: Wellings 4.2 & 4.4

3 3 The System Clock The JVM exposes a system clock:The JVM exposes a system clock: java.lang.System { static long currentTimeMillis(); } Also used by new java.util.Date(); to initialise to current time.Also used by new java.util.Date(); to initialise to current time. Returns milliseconds since midnight January 1 st 1970 GMT (like “UNIX time”).Returns milliseconds since midnight January 1 st 1970 GMT (like “UNIX time”). Depends on accuracy and granularity of underlying hardware clockDepends on accuracy and granularity of underlying hardware clock –Accuracy = How close it is to the real time –Granularity = The size of the “tick” (e.g. clock step) Note: may be larger than nominal resolution (e.g. 10ms in Java) Try ClockGranularity.java

4 4 Busy waiting delay public class BusyDelay { public static void main(String [] args) { public static void main(String [] args) { long start = System.currentTimeMillis(); long start = System.currentTimeMillis(); long delay = 1000; long delay = 1000; while (System.currentTimeMillis() < start+delay) while (System.currentTimeMillis() < start+delay) ; } ; }} Starting time “Current” time Target end time “Busy” loop – Inefficient – “wastes” CPU

5 5 Sleep The system allows a thread to perform a relative delay:The system allows a thread to perform a relative delay: java.lang.Thread { static void sleep(long millis); } java.lang.Thread { static void sleep(long millis); } N.B. delay is a minimum – see laterN.B. delay is a minimum – see later JVM can map request to OS sleepJVM can map request to OS sleep –Avoids busy waiting – more efficient: clock- watching is delegated to JVM and thence OS Compare CPU utilisation for BusyDelay & SleepDelay

6 6 Sleep delay public class SleepDelay { public static void main(String [] args) { public static void main(String [] args) { long delay = 1000; long delay = 1000; try { try { Thread.sleep(delay); Thread.sleep(delay); } catch(InterruptedException ie) } catch(InterruptedException ie) { /*ignore*/ } { /*ignore*/ } }} Relative delay time May be woken by Thread.interrupt() – see later notes

7 7 Sleep Granularity Time specified by program Granularity difference between clock and sleep time Interrupts disabled Thread runnable here but not executing Thread executing Time Local drift © Andy Wellings 2004 – from Wellings figure 4.1

8 8 Absolute delays Clock granularity, pre-emption and compute time make exact timing of sleep and code impossibleClock granularity, pre-emption and compute time make exact timing of sleep and code impossible Approximated by sleeping until (after) a specific target timeApproximated by sleeping until (after) a specific target time

9 9 Drifting clock public class DriftingClock { public static void main(String [] args) { public static void main(String [] args) { long delay = 1000; // 1 second = 1000 ms long delay = 1000; // 1 second = 1000 ms while(true) { while(true) { try { try { Thread.sleep(delay); Thread.sleep(delay); } catch(InterruptedException ie) } catch(InterruptedException ie) { /*ignore*/ } { /*ignore*/ } System.out.println("Tick at "+ System.out.println("Tick at "+ System.currentTimeMillis()); System.currentTimeMillis()); } }} Execution and preemption time ignored Granularity and preemption time ignored Absolute time errors accumulate

10 10 Absolute delay example public class SleepAbsoluteDelay { public static void main(String [] args) { public static void main(String [] args) { long start = System.currentTimeMillis(); long start = System.currentTimeMillis(); // next 10 second boundary // next 10 second boundary long tenseconds = 10*1000; long tenseconds = 10*1000; long end = ((start+tenseconds) / tenseconds)* long end = ((start+tenseconds) / tenseconds)* tenseconds; tenseconds; long delay = end-start; long delay = end-start; try { try { Thread.sleep(delay); Thread.sleep(delay); } catch(InterruptedException ie) { /*ignore*/ } } catch(InterruptedException ie) { /*ignore*/ } long now = System.currentTimeMillis(); long now = System.currentTimeMillis(); }} N.B. integer arithmetic

11 11 Time-outs on wait() Default wait() blocks thread indefinitely until notifiedDefault wait() blocks thread indefinitely until notified Possible to set maximum wait time:Possible to set maximum wait time: –java.lang.Object { void wait(long millis); void wait(long millis, long nanos); } E.g. forE.g. for –error detection (e.g. deadlock, message loss) –timed protocols

12 12 Timed-wait notes wait(0) = wait(0,0) = wait()wait(0) = wait(0,0) = wait() Cannot distinguish time-out from notifyCannot distinguish time-out from notify –Neither raises an exception (unlike interrupt) Consider notify “at the same time” as timeoutConsider notify “at the same time” as timeout –Just before => thread is woken by notify, waits for lock and returns just after timeout time –Just after => thread is woken by time-out, waits for lock and returns just after timeout time

13 13 Timed-wait example See TimedWait.javaSee TimedWait.java // thread 1… synchronized(tw) { long start = System. long start = System. currentTimeMillis(); currentTimeMillis(); try { try { tw.wait(5*1000); tw.wait(5*1000); } catch (InterruptedException ie) {} } catch (InterruptedException ie) {} System.out.println ("Done: " +(System.currentTimeMillis()- start)+"ms"); System.out.println ("Done: " +(System.currentTimeMillis()- start)+"ms");} // thread 2… long delay = 4000+(new java.util.Random()). nextInt(2000); try { Thread.sleep(delay); } catch(InterruptedException ie) {} synchronized(tw) { tw.notify(); } Should never be (much) more than 5000ms

14 14 Java 1.5 extensions (JSR166) Better support for time granularityBetter support for time granularity java.lang.System { static long nanoTime(); } –See also next slide Other concurrency utilities:Other concurrency utilities: –java.util.concurrent, e.g. queues –java.util.concurrent.atomic – for lock-free thread-safe programming w. shared variables –java.util.concurrent.locks – various lock utility classes

15 15 java.util.concurrent.TimeUnit package java.util.concurrent; public final enum TimeUnit { // available granularities MICROSECONDS, MILLISECONDS, NANOSECONDS, SECONDS; // utilities to manipulate times long convert(long duration, TimeUnit units); long toNanos(long duration); // timed operations in this granularity void sleep(long timeout) throws InterruptedException; void timedWait(Object monitor, long timeout) throws InterruptedException; void timedJoin(Thread thread, long timeout) throws InterruptedException; } e.g. see SleepTimeUnitsDelay

16 16 Events, TimerTasks and Timers A java.util.TimerTask is a Runnable object that represents a unit of workA java.util.TimerTask is a Runnable object that represents a unit of work –E.g. a GUI redraw or update A java.util.Timer represents a background thread that executes a set of TimerTask s non- concurrently:A java.util.Timer represents a background thread that executes a set of TimerTask s non- concurrently: –Enforces order –Avoids overhead of multiple threads or thread per task

17 17 java.util.TimerTask package java.util; public abstract class TimerTask implements Runnable { protected TimerTask(); // cancel task before (next) run public boolean cancel(); // most recent release time public long scheduledExecutionTime(); // actual task code – override public abstract void run(); }

18 18 java.util.Timer package java.util; public class Timer { Timer(); Timer(boolean isDaemon); void cancel(); // one-shot void schedule(TimerTask task, long delay); void schedule(TimerTask task, java.util.Date time); // repeating void schedule(TimerTask task, java.util.Date firstTime, long period); void schedule(TimerTask task, long delay, long period); void scheduleAtFixedRate(TimerTask task, java.util.Date firstTime, long period); void scheduleAtFixedRate(TimerTask task, long delay, long period); } package java.util; public class Timer { Timer(); Timer(boolean isDaemon); void cancel(); // one-shot void schedule(TimerTask task, long delay); void schedule(TimerTask task, java.util.Date time); // repeating void schedule(TimerTask task, java.util.Date firstTime, long period); void schedule(TimerTask task, long delay, long period); void scheduleAtFixedRate(TimerTask task, java.util.Date firstTime, long period); void scheduleAtFixedRate(TimerTask task, long delay, long period); }

19 19 Timer example import java.util.Timer; import java.util.TimerTask; public class DriftingTimerClock { static class TickTask extends TimerTask { static class TickTask extends TimerTask { int count = 0; int count = 0; public void run() { public void run() { System.out.println("Tick "+(count++)+"!"); System.out.println("Tick "+(count++)+"!"); } } public static void main(String [] args) { public static void main(String [] args) { Timer timer = new Timer(); Timer timer = new Timer(); // in 1 second, every second // in 1 second, every second timer.schedule(new TickTask(), 1000, 1000); timer.schedule(new TickTask(), 1000, 1000); }} To avoid drift use timer.scheduleAtFixedRate(…)

20 20 Summary Access to the system clock can support simple timingAccess to the system clock can support simple timing Thread.sleep allows efficient relative delaysThread.sleep allows efficient relative delays –Sleep time is a minimum –Care is needed to avoid cumulative errors/drift wait() can have a timeout specifiedwait() can have a timeout specified –But timeout and notify cannot be distinguished java.util.Timer and TimerTask support sequential scheduling of one-shot and repeated tasks on a shared threadjava.util.Timer and TimerTask support sequential scheduling of one-shot and repeated tasks on a shared thread –Avoiding per-task thread overhead, –preventing concurrency between tasks


Download ppt "1 G53SRP: Clocks and Time in Java Chris Greenhalgh School of Computer Science."

Similar presentations


Ads by Google