All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.spy.memcached.compat.SyncThread Maven / Gradle / Ivy

The newest version!
// Copyright (c) 2006  Dustin Sallings 

package net.spy.memcached.compat;

import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

/**
 * Thread that invokes a callable multiple times concurrently.
 */
public class SyncThread extends SpyThread {

  private final Callable callable;
  private final CyclicBarrier barrier;
  private final CountDownLatch latch;
  private Throwable throwable = null;
  private T rv = null;

  /**
   * Get a SyncThread that will call the given callable when the given
   * barrier allows it past.
   *
   * @param b the barrier
   * @param c the callable
   */
  public SyncThread(CyclicBarrier b, Callable c) {
    super("SyncThread");
    setDaemon(true);
    callable = c;
    barrier = b;
    latch = new CountDownLatch(1);
    start();
  }

  /**
   * Wait for the barrier, invoke the callable and capture the result or an
   * exception.
   */
  @Override
  public void run() {
    try {
      barrier.await();
      rv = callable.call();
    } catch (Throwable t) {
      throwable = t;
    }
    latch.countDown();
  }

  /**
   * Get the result from the invocation.
   *
   * @return the result
   * @throws Throwable if an error occurred when evaluating the callable
   */
  public T getResult() throws Throwable {
    latch.await();
    if (throwable != null) {
      throw throwable;
    }
    return rv;
  }

  /**
   * Get a collection of SyncThreads that all began as close to the
   * same time as possible and have all completed.
   *
   * @param       the result type of the SyncThread
   * @param num      the number of concurrent threads to execute
   * @param callable the thing to call
   * @return the completed SyncThreads
   * @throws InterruptedException if we're interrupted during join
   */
  public static  Collection> getCompletedThreads(
          int num, Callable callable) throws InterruptedException {
    Collection> rv = new ArrayList>(num);

    CyclicBarrier barrier = new CyclicBarrier(num);
    for (int i = 0; i < num; i++) {
      rv.add(new SyncThread(barrier, callable));
    }

    for (SyncThread t : rv) {
      t.join();
    }

    return rv;
  }

  /**
   * Get the distinct result count for the given callable at the given
   * concurrency.
   *
   * @param       the type of the callable
   * @param num      the concurrency
   * @param callable the callable to invoke
   * @return the number of distinct (by identity) results found
   * @throws Throwable if an exception occurred in one of the invocations
   */
  public static  int getDistinctResultCount(int num, Callable callable)
          throws Throwable {
    IdentityHashMap found = new IdentityHashMap();
    Collection> threads = getCompletedThreads(num, callable);
    for (SyncThread s : threads) {
      found.put(s.getResult(), new Object());
    }
    return found.size();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy