code: // from gee.cs.oswego.edu/home/jsr166/jsr166
  
  package jsr166tests.loops;
  
  /*
   * Written by Doug Lea with assistance from members of JCP JSR-166
   * Expert Group and released to the public domain, as explained at
   * http://creativecommons.org/licenses/publicdomain
   */
  
  import java.util.*;
  import java.util.concurrent.*;
  import java.util.concurrent.atomic.*;
  import java.util.concurrent.locks.*;
  
  public class ConcurrentDequeLoops {
      static final ExecutorService pool = Executors.newCachedThreadPool();
      static AtomicInteger totalItems;
      static boolean print = false;
  
      public static void main(String[] args) throws Exception {
          int maxStages = 8;
          int items = 1000000;
  
          Class klass = null;
          if (args.length > 0) {
              try {
                  klass = Class.forName(args[0]);
              } catch (ClassNotFoundException e) {
                  throw new RuntimeException("Class " + args[0] + " not found.");
              }
          }
          else
              throw new Error();
  
          if (args.length > 1)
              maxStages = Integer.parseInt(args[1]);
  
          System.out.print("Class: " + klass.getName());
          System.out.println(" stages: " + maxStages);
  
          print = false;
          System.out.println("Warmup...");
          oneRun(klass, 1, items);
          Thread.sleep(100);
          oneRun(klass, 1, items);
          Thread.sleep(100);
          print = true;
  
          int k = 1;
          for (int i = 1; i <= maxStages;) {
              oneRun(klass, i, items);
              if (i == k) {
                  k = i << 1;
                  i = i + (i >>> 1);
              }
              else
                  i = k;
          }
          pool.shutdown();
     }
  
      static class Stage implements Callable<Integer> {
          final Deque<Integer> queue;
          final CyclicBarrier barrier;
          final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
          int items;
          Stage (Deque<Integer> q, CyclicBarrier b, int items) {
              queue = q;
              barrier = b;
              this.items = items;
          }
  
          public Integer call() {
              // Repeatedly take something from queue if possible,
              // transform it, and put back in.
              try {
                  barrier.await();
                  int l = (int) System.nanoTime();
                  int takes = 0;
                  for (;;) {
                      Integer item;
                      int rnd = rng.next();
                      if ((rnd & 1) == 0)
                          item = queue.pollFirst();
                      else
                          item = queue.pollLast();
                      if (item != null) {
                          ++takes;
                          l += LoopHelpers.compute2(item.intValue());
                      }
                      else if (takes != 0) {
                          totalItems.getAndAdd(-takes);
                          takes = 0;
                      }
                      else if (totalItems.get() <= 0)
                          break;
                      l = LoopHelpers.compute1(l);
                      if (items > 0) {
                          --items;
                          Integer res = new Integer(l);
                          if ((rnd & 16) == 0)
                              queue.addFirst(res);
                          else
                              queue.addLast(res);
                      }
                      else { // spinwait
                          for (int k = 1 + (l & 15); k != 0; --k)
                              l = LoopHelpers.compute1(LoopHelpers.compute2(l));
                          if ((l & 3) == 3) {
                              Thread.sleep(1);
                          }
                      }
                  }
                  return new Integer(l);
              }
              catch (Exception ie) {
                  ie.printStackTrace();
                  throw new Error("Call loop failed");
              }
          }
      }
  
      static void oneRun(Class klass, int n, int items) throws Exception {
          Deque<Integer> q = (Deque<Integer>) klass.newInstance();
          LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
          CyclicBarrier barrier = new CyclicBarrier(n + 1, timer);
          totalItems = new AtomicInteger(n * items);
          ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(n);
          for (int i = 0; i < n; ++i)
              results.add(pool.submit(new Stage(q, barrier, items)));
  
          if (print)
              System.out.print("Threads: " + n + "\t:");
          barrier.await();
          int total = 0;
          for (int i = 0; i < n; ++i) {
              Future<Integer> f = results.get(i);
              Integer r = f.get();
              total += r.intValue();
          }
          long endTime = System.nanoTime();
          long time = endTime - timer.startTime;
          if (print)
              System.out.println(LoopHelpers.rightJustify(time / (items * n)) + " ns per item");
          if (total == 0) // avoid overoptimization
              System.out.println("useless result: " + total);
  
      }
  }
  