RFR for bug JDK-8004807: java/util/Timer/Args.java failing intermittently in HS testing

Eric Wang yiming.wang at oracle.com
Wed Jun 4 01:12:26 UTC 2014


Hi Martin,

To sleep(1000) is not enough to reproduce the failure, because it is 
much lower than the period DELAY_MS (10*1000) of the repeated task 
created by "scheduleAtFixedRate(t, counter(y3), past, DELAY_MS)".

Try sleep(DELAY_MS), the failure can be reproduced.

Thanks,
Eric
On 2014/6/4 8:33, Martin Buchholz wrote:
> On Tue, Jun 3, 2014 at 11:12 AM, roger riggs <roger.riggs at oracle.com> wrote:
>
>> Hi Martin,
>>
>> Is it possible that the main thread takes too long to go from y3.await()
>> to the t.cancel() that the fixed rate timer (y3) gets called again?
>>
>>
> If that was true, adding a sleep(1000) after the awaits in my version would
> cause consistent failures, but I don't see any.
>
>
>> It seems unlikely, but with the printf, its not just compute time.
>> Canceling the timer before the printf would likely reduce the failures.
>>
> Again, we need to understand the failures independently.  I have never seen
> this test fail.  Is there some environmental thing?
>
>
>> Another alternative is to increase the period to allow more time for the
>> main thread to respond.
>>
> I agree that this would make the test more robust, and that's one thing my
> version does.
>
>
>>  From the error, its not clear which timer was called an extra time.
>>
>>
> True.
>   My updated version tries to fix that problem.
> Hopefully you can report which task is being scheduled too often.
>
>
> import java.util.*;
> import java.util.concurrent.*;
>
> public class Args {
>      static final long DELAY_MS = 10 * 1000L;
>
>      void schedule(final Timer t, final TimerTask task, final Date d) {
>          t.schedule(task, d);
>          assertThrows
>              (IllegalStateException.class,
>               () -> t.schedule(task, d));
>      }
>
>      void schedule(final Timer t, final TimerTask task, final Date d, final
> long period) {
>          t.schedule(task, d, period);
>          assertThrows
>              (IllegalStateException.class,
>               () -> t.schedule(task, d, period));
>      }
>
>      void scheduleAtFixedRate(final Timer t, final TimerTask task, final
> Date d, final long period) {
>          t.scheduleAtFixedRate(task, d, period);
>          assertThrows
>              (IllegalStateException.class,
>               () -> t.scheduleAtFixedRate(task, d, period));
>      }
>
>      TimerTask counter(final CountDownLatch latch) {
>          return new TimerTask() { public void run() {
>              if (latch.getCount() == 0)
>                  fail(String.format("Latch counted down too many times: " +
> latch));
>              latch.countDown();
>          }};
>      }
>
>      TimerTask nop() {
>          return new TimerTask() { public void run() { }};
>      }
>
>      void test(String[] args) throws Throwable {
>          final Timer t = new Timer();
>          try {
>              test(t);
>          } finally {
>              // Ensure this test doesn't interfere with subsequent
>              // tests even in case of failure.
>              t.cancel();
>          }
>
>          // Attempts to schedule tasks on a cancelled Timer result in ISE.
>
>          final Date past = new Date(System.currentTimeMillis() - DELAY_MS);
>          final Date future = new Date(System.currentTimeMillis() + DELAY_MS);
>          assertThrows
>              (IllegalStateException.class,
>               () -> t.schedule(nop(), 42),
>               () -> t.schedule(nop(), 42),
>               () -> t.schedule(nop(), past),
>               () -> t.schedule(nop(), 42, 42),
>               () -> t.schedule(nop(), past, 42),
>               () -> t.scheduleAtFixedRate(nop(), 42, 42),
>               () -> t.scheduleAtFixedRate(nop(), past, 42),
>               () -> t.scheduleAtFixedRate(nop(), future, 42));
>      }
>
>      void test(Timer t) throws Throwable {
>          final TimerTask x = new TimerTask() { public void run() {}};
>          assertThrows
>              (IllegalArgumentException.class,
>               () -> t.schedule(x, -42),
>               () -> t.schedule(x, new Date(-42)),
>
>               () -> t.schedule(x, Long.MAX_VALUE),
>               () -> t.schedule(x, -42, 42),
>               () -> t.schedule(x, new Date(-42), 42),
>               () -> t.schedule(x, Long.MAX_VALUE, 42),
>               () -> t.schedule(x, 42, 0),
>               () -> t.schedule(x, new Date(42), 0),
>               () -> t.schedule(x, 42, -42),
>               () -> t.schedule(x, new Date(42), -42),
>
>               () -> t.scheduleAtFixedRate(x, -42, 42),
>               () -> t.scheduleAtFixedRate(x, new Date(-42), 42),
>               () -> t.scheduleAtFixedRate(x, Long.MAX_VALUE, 42),
>               () -> t.scheduleAtFixedRate(x, 42, 0),
>               () -> t.scheduleAtFixedRate(x, new Date(42), 0),
>               () -> t.scheduleAtFixedRate(x, 42, -42),
>               () -> t.scheduleAtFixedRate(x, new Date(42), -42));
>
>          assertThrows
>              (NullPointerException.class,
>               () -> t.schedule(null, 42),
>               () -> t.schedule(x, (Date)null),
>
>               () -> t.schedule(null, 42, 42),
>               () -> t.schedule(x, (Date)null, 42),
>
>               () -> t.scheduleAtFixedRate(null, 42, 42),
>               () -> t.scheduleAtFixedRate(x, (Date)null, 42));
>
>          // Create local classes for clearer diagnostics in case of failure
>          class OneShotLatch extends CountDownLatch {
>              OneShotLatch() { super(1); }
>          }
>          class FixedRateLatch extends CountDownLatch {
>              FixedRateLatch() { super(11); }
>          }
>          class FixedDelayLatch extends CountDownLatch {
>              FixedDelayLatch() { super(1); }
>          }
>          final CountDownLatch y1 = new OneShotLatch();
>          final CountDownLatch y2 = new FixedDelayLatch();
>          final CountDownLatch y3 = new FixedRateLatch();
>          final long start = System.currentTimeMillis();
>          final Date past = new Date(start - (10 * DELAY_MS + DELAY_MS / 2));
>
>          schedule(           t, counter(y1), past);
>          schedule(           t, counter(y2), past, DELAY_MS);
>          scheduleAtFixedRate(t, counter(y3), past, DELAY_MS);
>          y1.await();
>          y2.await();
>          y3.await();
>
>          final long elapsed = System.currentTimeMillis() - start;
>          if (elapsed >= DELAY_MS / 2)
>              fail(String.format("Test took too long: elapsed=%d%n",
> elapsed));
>      }
>
>      //--------------------- Infrastructure ---------------------------
>      volatile int passed = 0, failed = 0;
>      void pass() {passed++;}
>      void fail() {failed++; Thread.dumpStack();}
>      void fail(String msg) {System.err.println(msg); fail();}
>      void unexpected(Throwable t) {failed++; t.printStackTrace();}
>      void check(boolean cond) {if (cond) pass(); else fail();}
>      void equal(Object x, Object y) {
>          if (x == null ? y == null : x.equals(y)) pass();
>          else fail(x + " not equal to " + y);}
>      public static void main(String[] args) throws Throwable {
>          new Args().instanceMain(args);}
>      void instanceMain(String[] args) throws Throwable {
>          try {test(args);} catch (Throwable t) {unexpected(t);}
>          System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
>          if (failed > 0) throw new AssertionError("Some tests failed");}
>      interface F { void f() throws Throwable; }
>      void assertThrows(Class<? extends Throwable> k, F... fs) {
>          for (F f : fs)
>              try {f.f(); fail("Expected " + k.getName() + " not thrown");}
>              catch (Throwable t) {
>                  if (k.isAssignableFrom(t.getClass())) pass();
>                  else unexpected(t);}}
> }




More information about the core-libs-dev mailing list