Quote: | |||
06.22.2005 - Java, not as good as it should be?
Ive been trying to get my Java groove on, programming a bunch of prototypes - testing this and that. One of the applications was a Calendar that would highlight the current day - that should run 24/7 etc. However, after some testing I noticed a huge issue with Java that I would consider a "bug". I've been e-mailing my Java professor over the past few days trying to come up w/ a solution but here it is in short. If you have a Thread or Runnable instance, including Timer, and you set your system time backwards (say by a day) - the application completely stops. If you set it forward, the thread will try and catch up to the system time - so it executes the appropriate event several rapid times (essentially going bezerk). I should mention here that .NET appears not to have this issue - but that is because I think it uses the GetTickCount() - or the API to determine how long the system has been running. I'm not the only one who had this issue but it's been in existence since Java 1.3 from what I gather from this bug report: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4290274 A sample block of code and it's run of when I set the system time forward:
|
Code: Show/Hide int intChecks = 50; int intIterations = 25000; long[] lngDuration = new long[intChecks]; double[] dblRuntime = new double[intChecks]; DecimalFormat objFormat = new DecimalFormat("#.#####"); // Setup variables and stuff here for(int intUpper = 0; intUpper < intChecks; ++intUpper) { long lngStart = System.currentTimeMillis(); for(int intCounter = 0; intCounter < intIterations; ++intCounter) { // Code to time goes here } lngDuration[intUpper] = System.currentTimeMillis() - lngStart; dblRuntime[intUpper] = (double) lngDuration[intUpper] / (double) intIterations; System.out.println("Duration: " + lngDuration[intUpper]); System.out.println("Runtime: " + objFormat.format(dblRuntime[intUpper])); } long lngTotal = 0; double dblTotal = 0; for(int intCounter = 0; intCounter < intChecks; ++intCounter) { lngTotal += lngDuration[intCounter]; dblTotal += dblRuntime[intCounter]; } System.out.println("-----"); System.out.println(); System.out.println("Avg Duration: " + (lngTotal / intChecks)); System.out.println("Avg Runtime: " + objFormat.format((dblTotal / intChecks))); |
Code: Show/Hide import java.util.Date;
public class TestThread implements Runnable { private Thread thisThread; public static void main(String[] args) { TestThread tt = new TestThread(); System.out.println("A test of a Thread that should sleep for 1 second."); tt.run(); } public TestThread() { thisThread = new Thread(this, "Test"); //thisThread.start(); } public void run() { while (true) { System.out.println("" + new Date()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } |
Quote: |
A test of a Thread that should sleep for 1 second.
Thu Jun 23 12:56:41 EDT 2005 Thu Jun 23 12:56:42 EDT 2005 Thu Jun 23 12:56:43 EDT 2005 Thu Jun 23 12:56:44 EDT 2005 Thu Jun 23 12:56:45 EDT 2005 Thu Jun 23 12:56:46 EDT 2005 |
Code: Show/Hide import java.util.*; public class TimerTest { public static void main(String[] args) { BrainsTimer testTimer = new BrainsTimer(1000, 1000) { public boolean timerEventFired() { System.out.println("---TIME---"); System.out.println("TIME:" + new Date()); System.out.println("//---TIME---"); return true; } }; } } abstract class BrainsTimer extends Thread { private long delay; private long period; public BrainsTimer(long delay, long period) { this.delay = delay; this.period = period; this.start(); } //returns true if it wishes to continue being scheduled public abstract boolean timerEventFired(); public void run() { try { Thread.sleep(delay); while (timerEventFired()) { Thread.sleep(period); } } catch (InterruptedException e) { e.printStackTrace(); } } } |