alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (UninterruptibleFutureTest.java)

This example Java source code file (UninterruptibleFutureTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

boolean, callable, exception, executionexception, futuretask, interruptedexception, override, result, runtimeexception, seconds, settablefuture, sleepingrunnable, teardownstack, threading, threads, timeoutexception

The UninterruptibleFutureTest.java Java example source code

/*
 * Copyright (C) 2009 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.util.concurrent;

import static com.google.common.util.concurrent.InterruptionUtil.repeatedlyInterruptTestThread;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.common.testing.TearDown;
import com.google.common.testing.TearDownStack;

import junit.framework.TestCase;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

// TODO(azana/cpovirk): Should this be merged into UninterruptiblesTest?
/**
 * Unit test for {@link Uninterruptibles#getUninterruptibly}
 *
 * @author Kevin Bourrillion
 * @author Chris Povirk
 */
public class UninterruptibleFutureTest extends TestCase {
  private SleepingRunnable sleeper;
  private Future<Boolean> delayedFuture;

  private final TearDownStack tearDownStack = new TearDownStack();

  @Override protected void setUp() {
    final ExecutorService executor = Executors.newSingleThreadExecutor();
    tearDownStack.addTearDown(new TearDown() {
      @Override
      public void tearDown() {
        executor.shutdownNow();
      }
    });
    sleeper = new SleepingRunnable(1000);
    delayedFuture = executor.submit(sleeper, true);

    tearDownStack.addTearDown(new TearDown() {
      @Override
      public void tearDown() {
        Thread.interrupted();
      }
    });
  }

  @Override
  protected void tearDown() {
    tearDownStack.runTearDown();
  }

  /**
   * This first test doesn't test anything in Uninterruptibles, just
   * demonstrates some normal behavior of futures so that you can contrast
   * the next test with it.
   */

  public void testRegularFutureInterrupted() throws ExecutionException {

    /*
     * Here's the order of events that we want.
     *
     * 1. The client thread begins to block on a get() call to a future.
     * 2. The client thread is interrupted sometime before the result would be
     *   available.
     * 3. We expect the client's get() to throw an InterruptedException.
     * 4. We expect the client thread's interrupt state to be false.
     * 5. The client thread again makes a blocking call to get().
     * 6. Now the result becomes available.
     * 7. We expect get() to return this result.
     * 8. We expect the test thread's interrupt state to be false.
     */
    InterruptionUtil.requestInterruptIn(200, TimeUnit.MILLISECONDS);

    assertFalse(Thread.interrupted());
    try {
      delayedFuture.get(1000, TimeUnit.MILLISECONDS);
      fail("expected to be interrupted");
    } catch (InterruptedException expected) {
    } catch (TimeoutException e) {
      throw new RuntimeException(e);
    }

    // we were interrupted, but it's been cleared now
    assertFalse(Thread.interrupted());

    assertFalse(sleeper.completed);
    try {
      assertTrue(delayedFuture.get());
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
    assertTrue(sleeper.completed);
  }

  public void testMakeUninterruptible_timeoutPreservedThroughInterruption()
      throws ExecutionException {

    repeatedlyInterruptTestThread(100, tearDownStack);

    try {
      getUninterruptibly(delayedFuture, 500, TimeUnit.MILLISECONDS);
      fail("expected to time out");
    } catch (TimeoutException expected) {
    }
    assertTrue(Thread.interrupted()); // clears the interrupt state, too

    assertFalse(sleeper.completed);
    assertTrue(getUninterruptibly(delayedFuture));

    assertTrue(Thread.interrupted()); // clears the interrupt state, too
    assertTrue(sleeper.completed);
  }

  private static class SleepingRunnable implements Runnable {
    final int millis;
    volatile boolean completed;

    public SleepingRunnable(int millis) {
      this.millis = millis;
    }
    @Override
    public void run() {
      try {
        Thread.sleep(millis);
      } catch (InterruptedException wontHappen) {
        throw new AssertionError();
      }
      completed = true;
    }
  }

  public void testMakeUninterruptible_untimed_uninterrupted()
      throws Exception {
    runUntimedInterruptsTest(0);
  }

  public void testMakeUninterruptible_untimed_interrupted()
      throws Exception {
    runUntimedInterruptsTest(1);
  }

  public void testMakeUninterruptible_untimed_multiplyInterrupted()
      throws Exception {
    runUntimedInterruptsTest(38);
  }

  public void testMakeUninterruptible_timed_uninterrupted()
      throws Exception {
    runTimedInterruptsTest(0);
  }

  public void testMakeUninterruptible_timed_interrupted()
      throws Exception {
    runTimedInterruptsTest(1);
  }

  public void testMakeUninterruptible_timed_multiplyInterrupted()
      throws Exception {
    runTimedInterruptsTest(38);
  }

  private static void runUntimedInterruptsTest(int times)
      throws InterruptedException, ExecutionException, TimeoutException {
    SettableFuture<String> future = SettableFuture.create();
    FutureTask<Boolean> interruptReporter =
        untimedInterruptReporter(future, false);

    runNInterruptsTest(times, future, interruptReporter);
  }

  private static void runTimedInterruptsTest(int times)
      throws InterruptedException, ExecutionException, TimeoutException {
    SettableFuture<String> future = SettableFuture.create();
    FutureTask<Boolean> interruptReporter =
        timedInterruptReporter(future);

    runNInterruptsTest(times, future, interruptReporter);
  }

  private static void runNInterruptsTest(int times, SettableFuture<String> future,
      FutureTask<Boolean> interruptReporter)
      throws InterruptedException, ExecutionException, TimeoutException {
    Thread waitingThread = new Thread(interruptReporter);
    waitingThread.start();
    for (int i = 0; i < times; i++) {
      waitingThread.interrupt();
    }

    future.set(RESULT);

    assertEquals(times > 0, (boolean) interruptReporter.get(20, SECONDS));
  }

  /**
   * Confirms that the test code triggers {@link InterruptedException} in a
   * standard {@link Future}.
   */

  public void testMakeUninterruptible_plainFutureSanityCheck()
      throws Exception {
    SettableFuture<String> future = SettableFuture.create();
    FutureTask<Boolean> wasInterrupted =
        untimedInterruptReporter(future, true);

    Thread waitingThread = new Thread(wasInterrupted);
    waitingThread.start();
    waitingThread.interrupt();
    try {
      wasInterrupted.get();
      fail();
    } catch (ExecutionException expected) {
      assertTrue(expected.getCause().toString(),
          expected.getCause() instanceof InterruptedException);
    }
  }

  public void testMakeUninterruptible_timedGetZeroTimeoutAttempted()
      throws TimeoutException, ExecutionException {
    SettableFuture<String> future = SettableFuture.create();
    future.set(RESULT);
    /*
     * getUninterruptibly should call the timed get method once with a
     * wait of 0 seconds (and it should succeed, since the result is already
     * available).
     */
    assertEquals(RESULT, getUninterruptibly(future, 0, SECONDS));
  }

  public void testMakeUninterruptible_timedGetNegativeTimeoutAttempted()
      throws TimeoutException, ExecutionException {
    SettableFuture<String> future = SettableFuture.create();
    future.set(RESULT);
    /*
     * The getUninterruptibly should call the timed get method once with a
     * wait of -1 seconds (and it should succeed, since the result is already
     * available).
     */
    assertEquals(RESULT, getUninterruptibly(future, -1, SECONDS));
  }

  private static FutureTask<Boolean> untimedInterruptReporter(
      final Future<?> future, final boolean allowInterruption) {
    return new FutureTask<Boolean>(new Callable() {
      @Override
      public Boolean call() throws Exception {
        Object actual;
        if (allowInterruption) {
          actual = future.get();
        } else {
          actual = getUninterruptibly(future);
        }
        assertEquals(RESULT, actual);
        return Thread.interrupted();
      }
    });
  }

  private static FutureTask<Boolean> timedInterruptReporter(
      final Future<?> future) {
    return new FutureTask<Boolean>(new Callable() {
      @Override
      public Boolean call() throws Exception {
        assertEquals(RESULT, getUninterruptibly(future, 10, MINUTES));
        return Thread.interrupted();
      }
    });
  }

  private static final String RESULT = "result";
}

Other Java examples (source code examples)

Here is a short list of links related to this Java UninterruptibleFutureTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.