1 / 20

G53SRP: Clocks and Time in Java

G53SRP: Clocks and Time in Java. Chris Greenhalgh School of Computer Science. Contents. The system clock Sleeping Absolute delays Time-outs on wait Java 1.5 extensions: TimeUnit, nanoTime Events, Timers and TimerTasks Book: Wellings 4.2 & 4.4. The System Clock.

tanuja
Télécharger la présentation

G53SRP: Clocks and Time in Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Contents • The system clock • Sleeping • Absolute delays • Time-outs on wait • Java 1.5 extensions: TimeUnit, nanoTime • Events, Timers and TimerTasks • Book: Wellings 4.2 & 4.4

  3. The 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. • Returns milliseconds since midnight January 1st 1970 GMT (like “UNIX time”). • Depends 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. Starting time “Current” time Target end time “Busy” loop – Inefficient – “wastes” CPU Busy waiting delay public class BusyDelay { public static void main(String [] args) { long start = System.currentTimeMillis(); long delay = 1000; while (System.currentTimeMillis() < start+delay) ; } }

  5. Sleep • The system allows a thread to perform a relative delay: java.lang.Thread { static void sleep(long millis);} • N.B. delay is a minimum – see later • JVM 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. Relative delay time May be woken by Thread.interrupt()– see later notes Sleep delay public class SleepDelay { public static void main(String [] args) { long delay = 1000; try { Thread.sleep(delay); } catch(InterruptedException ie) { /*ignore*/ } } }

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

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

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

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

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

  12. Timed-wait notes • wait(0) = wait(0,0) = wait() • Cannot distinguish time-out from notify • Neither raises an exception (unlike interrupt) • Consider 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. See TimedWait.java // thread 1… synchronized(tw) { long start = System. currentTimeMillis(); try { tw.wait(5*1000); } catch (InterruptedException ie) {} 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 Timed-wait example

  14. Java 1.5 extensions (JSR166) • Better support for time granularity java.lang.System { static long nanoTime();} • See also next slide • 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. java.util.concurrent.TimeUnit package java.util.concurrent;public final enum TimeUnit { // available granularitiesMICROSECONDS, 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. Events, TimerTasks and Timers • A 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 TimerTasks non-concurrently: • Enforces order • Avoids overhead of multiple threads or thread per task

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

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

  20. Summary • Access to the system clock can support simple timing • Thread.sleep allows efficient relative delays • Sleep time is a minimum • Care is needed to avoid cumulative errors/drift • wait() 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 thread • Avoiding per-task thread overhead, • preventing concurrency between tasks

More Related