jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java
changeset 36231 52e0ee9847fb
parent 35394 282c3cb6a0c1
child 40817 4f5fb115676d
equal deleted inserted replaced
36230:ffcbf28059ee 36231:52e0ee9847fb
    30  * Expert Group and released to the public domain, as explained at
    30  * Expert Group and released to the public domain, as explained at
    31  * http://creativecommons.org/publicdomain/zero/1.0/
    31  * http://creativecommons.org/publicdomain/zero/1.0/
    32  */
    32  */
    33 
    33 
    34 import static java.util.concurrent.TimeUnit.MILLISECONDS;
    34 import static java.util.concurrent.TimeUnit.MILLISECONDS;
       
    35 import static java.util.concurrent.TimeUnit.NANOSECONDS;
    35 import static java.util.concurrent.TimeUnit.SECONDS;
    36 import static java.util.concurrent.TimeUnit.SECONDS;
    36 
    37 
    37 import java.util.ArrayList;
    38 import java.util.ArrayList;
    38 import java.util.HashSet;
    39 import java.util.HashSet;
    39 import java.util.List;
    40 import java.util.List;
    53 import java.util.concurrent.ScheduledThreadPoolExecutor;
    54 import java.util.concurrent.ScheduledThreadPoolExecutor;
    54 import java.util.concurrent.ThreadFactory;
    55 import java.util.concurrent.ThreadFactory;
    55 import java.util.concurrent.ThreadPoolExecutor;
    56 import java.util.concurrent.ThreadPoolExecutor;
    56 import java.util.concurrent.TimeoutException;
    57 import java.util.concurrent.TimeoutException;
    57 import java.util.concurrent.TimeUnit;
    58 import java.util.concurrent.TimeUnit;
       
    59 import java.util.concurrent.atomic.AtomicBoolean;
    58 import java.util.concurrent.atomic.AtomicInteger;
    60 import java.util.concurrent.atomic.AtomicInteger;
       
    61 import java.util.concurrent.atomic.AtomicLong;
    59 
    62 
    60 import junit.framework.Test;
    63 import junit.framework.Test;
    61 import junit.framework.TestSuite;
    64 import junit.framework.TestSuite;
    62 
    65 
    63 public class ScheduledExecutorSubclassTest extends JSR166TestCase {
    66 public class ScheduledExecutorSubclassTest extends JSR166TestCase {
   224         AtomicInteger count = new AtomicInteger(0);
   227         AtomicInteger count = new AtomicInteger(0);
   225         public void run() { count.getAndIncrement(); }
   228         public void run() { count.getAndIncrement(); }
   226     }
   229     }
   227 
   230 
   228     /**
   231     /**
   229      * scheduleAtFixedRate executes series of tasks at given rate
   232      * scheduleAtFixedRate executes series of tasks at given rate.
       
   233      * Eventually, it must hold that:
       
   234      *   cycles - 1 <= elapsedMillis/delay < cycles
   230      */
   235      */
   231     public void testFixedRateSequence() throws InterruptedException {
   236     public void testFixedRateSequence() throws InterruptedException {
   232         final CustomExecutor p = new CustomExecutor(1);
   237         final CustomExecutor p = new CustomExecutor(1);
   233         try (PoolCleaner cleaner = cleaner(p)) {
   238         try (PoolCleaner cleaner = cleaner(p)) {
   234             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
   239             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
   235                 long startTime = System.nanoTime();
   240                 final long startTime = System.nanoTime();
   236                 int cycles = 10;
   241                 final int cycles = 8;
   237                 final CountDownLatch done = new CountDownLatch(cycles);
   242                 final CountDownLatch done = new CountDownLatch(cycles);
   238                 Runnable task = new CheckedRunnable() {
   243                 final Runnable task = new CheckedRunnable() {
   239                     public void realRun() { done.countDown(); }};
   244                     public void realRun() { done.countDown(); }};
   240                 ScheduledFuture h =
   245                 final ScheduledFuture periodicTask =
   241                     p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
   246                     p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
   242                 await(done);
   247                 final int totalDelayMillis = (cycles - 1) * delay;
   243                 h.cancel(true);
   248                 await(done, totalDelayMillis + LONG_DELAY_MS);
   244                 double normalizedTime =
   249                 periodicTask.cancel(true);
   245                     (double) millisElapsedSince(startTime) / delay;
   250                 final long elapsedMillis = millisElapsedSince(startTime);
   246                 if (normalizedTime >= cycles - 1 &&
   251                 assertTrue(elapsedMillis >= totalDelayMillis);
   247                     normalizedTime <= cycles)
   252                 if (elapsedMillis <= cycles * delay)
   248                     return;
   253                     return;
       
   254                 // else retry with longer delay
   249             }
   255             }
   250             fail("unexpected execution rate");
   256             fail("unexpected execution rate");
   251         }
   257         }
   252     }
   258     }
   253 
   259 
   254     /**
   260     /**
   255      * scheduleWithFixedDelay executes series of tasks with given period
   261      * scheduleWithFixedDelay executes series of tasks with given period.
       
   262      * Eventually, it must hold that each task starts at least delay and at
       
   263      * most 2 * delay after the termination of the previous task.
   256      */
   264      */
   257     public void testFixedDelaySequence() throws InterruptedException {
   265     public void testFixedDelaySequence() throws InterruptedException {
   258         final CustomExecutor p = new CustomExecutor(1);
   266         final CustomExecutor p = new CustomExecutor(1);
   259         try (PoolCleaner cleaner = cleaner(p)) {
   267         try (PoolCleaner cleaner = cleaner(p)) {
   260             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
   268             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
   261                 long startTime = System.nanoTime();
   269                 final long startTime = System.nanoTime();
   262                 int cycles = 10;
   270                 final AtomicLong previous = new AtomicLong(startTime);
       
   271                 final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
       
   272                 final int cycles = 8;
   263                 final CountDownLatch done = new CountDownLatch(cycles);
   273                 final CountDownLatch done = new CountDownLatch(cycles);
   264                 Runnable task = new CheckedRunnable() {
   274                 final int d = delay;
   265                     public void realRun() { done.countDown(); }};
   275                 final Runnable task = new CheckedRunnable() {
   266                 ScheduledFuture h =
   276                     public void realRun() {
       
   277                         long now = System.nanoTime();
       
   278                         long elapsedMillis
       
   279                             = NANOSECONDS.toMillis(now - previous.get());
       
   280                         if (done.getCount() == cycles) { // first execution
       
   281                             if (elapsedMillis >= d)
       
   282                                 tryLongerDelay.set(true);
       
   283                         } else {
       
   284                             assertTrue(elapsedMillis >= d);
       
   285                             if (elapsedMillis >= 2 * d)
       
   286                                 tryLongerDelay.set(true);
       
   287                         }
       
   288                         previous.set(now);
       
   289                         done.countDown();
       
   290                     }};
       
   291                 final ScheduledFuture periodicTask =
   267                     p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
   292                     p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
   268                 await(done);
   293                 final int totalDelayMillis = (cycles - 1) * delay;
   269                 h.cancel(true);
   294                 await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
   270                 double normalizedTime =
   295                 periodicTask.cancel(true);
   271                     (double) millisElapsedSince(startTime) / delay;
   296                 final long elapsedMillis = millisElapsedSince(startTime);
   272                 if (normalizedTime >= cycles - 1 &&
   297                 assertTrue(elapsedMillis >= totalDelayMillis);
   273                     normalizedTime <= cycles)
   298                 if (!tryLongerDelay.get())
   274                     return;
   299                     return;
       
   300                 // else retry with longer delay
   275             }
   301             }
   276             fail("unexpected execution rate");
   302             fail("unexpected execution rate");
   277         }
   303         }
   278     }
   304     }
   279 
   305