Permalink
Browse files

add concurrent time test

  • Loading branch information...
1 parent 3b5f369 commit a388e4fa00bf86c094dc5d1d938ac02bbdffe8e5 @shenfeng shenfeng committed Feb 20, 2011
@@ -0,0 +1,109 @@
+package jcip.puzzle;
+
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import javax.annotation.concurrent.GuardedBy;
+
+public class ConcurrentQueenPuzzleSolver {
+
+ public static void main(String[] args) throws InterruptedException {
+ for (int i = 8; i < 100; ++i) {
+ long start = System.currentTimeMillis();
+ QueenPuzzle puzzle = new QueenPuzzle(i);
+ ConcurrentQueenPuzzleSolver solver = new ConcurrentQueenPuzzleSolver(
+ puzzle);
+ List<Move> result = solver.solve();
+ System.out.println("solve problem size of " + i + " takes time "
+ + (System.currentTimeMillis() - start) + " ms; result: "
+ + result);
+ }
+ }
+
+ final ValueLatch<Node<Position, Move>> solution = new ValueLatch<Node<Position, Move>>();
+ private final QueenPuzzle puzzle;
+
+ private final ExecutorService exec = Executors.newFixedThreadPool(50);
+
+ public List<Move> solve() throws InterruptedException {
+ try {
+ Position pos = puzzle.initialPosition();
+ exec.execute(newTask(pos, null, null));
+ // block until solution is found
+ Node<Position, Move> result = solution.getValue();
+ return result.asMoveList();
+ } finally {
+ exec.shutdown();
+ }
+ }
+
+ protected Runnable newTask(Position p, Move m, Node<Position, Move> prev) {
+ return new SolverTask(p, m, prev);
+ }
+
+ public ConcurrentQueenPuzzleSolver(QueenPuzzle puzzle) {
+ this.puzzle = puzzle;
+ ((ThreadPoolExecutor) exec)
+ .setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
+
+ }
+
+ class SolverTask extends Node<Position, Move> implements Runnable {
+
+ public SolverTask(Position pos, Move move, Node<Position, Move> prev) {
+ super(pos, move, prev);
+ }
+
+ @Override
+ public void run() {
+ if (solution.isSet())
+ return;
+ if (puzzle.isGoal(pos)) {
+ solution.setValue(this);
+ } else {
+ for (Move move : puzzle.legalMoves(pos)) {
+ Position newPos = puzzle.move(pos, move);
+ if (puzzle.isGoal(newPos)) {
+ solution.setValue(this);
+ return;
+ } else {
+ for (Move m : puzzle.legalMoves(newPos)) {
+ exec.execute(newTask(puzzle.move(newPos, m), m,
+ this));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static class ValueLatch<T> {
+
+ @GuardedBy("this")
+ private final CountDownLatch done = new CountDownLatch(1);
+ private T value;
+
+ public boolean isSet() {
+ return done.getCount() == 0;
+ }
+
+ public synchronized void setValue(T newValue) {
+ if (!isSet()) {
+ value = newValue;
+ done.countDown();
+ }
+ }
+
+ public T getValue() throws InterruptedException {
+ done.await();
+ synchronized (this) {
+ return value;
+ }
+ }
+ }
+
+}
@@ -0,0 +1,82 @@
+package jcip.puzzle;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class PQueenPuzzleSolver {
+
+ private final Puzzle<Position, Move> puzzle;
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ public PQueenPuzzleSolver(QueenPuzzle puzzle) {
+ this.puzzle = puzzle;
+ }
+
+ public List<Move> solve() throws InterruptedException, ExecutionException {
+ final ExecutorService exec = Executors.newFixedThreadPool(Runtime
+ .getRuntime().availableProcessors());
+ try {
+ final Position pos = puzzle.initialPosition();
+ final Node<Position, Move> init = new Node<Position, Move>(pos,
+ null, null);
+ CompletionService<List<Move>> completionService = new ExecutorCompletionService<List<Move>>(
+ exec);
+ for (final Move m : puzzle.legalMoves(pos)) {
+ completionService.submit(new Callable<List<Move>>() {
+ @Override
+ public List<Move> call() throws Exception {
+ Position newPos = puzzle.move(pos, m);
+ return search(new Node<Position, Move>(newPos, m, init));
+ }
+ });
+ }
+ while (true) {
+ Future<List<Move>> f = completionService.take();
+ List<Move> result = f.get();
+ if (result != null)
+ return result;
+ }
+ } finally {
+ exec.shutdownNow();
+ }
+ }
+
+ private List<Move> search(Node<Position, Move> node) {
+ if (latch.getCount() == 0)
+ return null;
+
+ if (puzzle.isGoal(node.pos)) {
+ latch.countDown();
+ return node.asMoveList();
+ }
+ for (Move move : puzzle.legalMoves(node.pos)) {
+ Position pos = puzzle.move(node.pos, move);
+ Node<Position, Move> child = new Node<Position, Move>(pos, move,
+ node);
+ List<Move> result = search(child);
+ if (result != null)
+ return result;
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws InterruptedException,
+ ExecutionException {
+ for (int i = 8; i < 100; ++i) {
+ long start = System.currentTimeMillis();
+ QueenPuzzle puzzle = new QueenPuzzle(i);
+ PQueenPuzzleSolver solver = new PQueenPuzzleSolver(puzzle);
+ List<Move> result = solver.solve();
+ System.out.println("solve problem size of " + i + " takes time "
+ + (System.currentTimeMillis() - start) + " ms; result: "
+ + result);
+ }
+ }
+}
@@ -32,9 +32,9 @@ public QueenPuzzleSolver(QueenPuzzle puzzle) {
}
public static void main(String[] args) {
- for (int i = 8; i < 100; ++i) {
+ for (int i = 0; i < 30; ++i) {
long start = System.currentTimeMillis();
- QueenPuzzle puzzle = new QueenPuzzle(i);
+ QueenPuzzle puzzle = new QueenPuzzle(29);
QueenPuzzleSolver solver = new QueenPuzzleSolver(puzzle);
List<Move> result = solver.solve();
System.out.println("solve problem size of " + i + " takes time "
@@ -0,0 +1,70 @@
+package jcip.puzzle;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Test;
+
+public class TestConcurrenTime {
+
+ private long f(int n) {
+ if (n < 3)
+ return 1;
+ else
+ return f(n - 1) + f(n - 2);
+ }
+
+ @Test
+ public void testF() {
+ for (int i = 0; i < 3; ++i) {
+ long l = System.currentTimeMillis();
+ // System.out.println(f(44));
+ QueenPuzzle puzzle = new QueenPuzzle(29);
+ QueenPuzzleSolver solver = new QueenPuzzleSolver(puzzle);
+ List<Move> result = solver.solve();
+ System.out.println(System.currentTimeMillis() - l);
+ }
+ }
+
+ private static class Task implements Runnable {
+
+ private AtomicLong time;
+
+ public Task(AtomicLong time) {
+ this.time = time;
+ }
+
+ @Override
+ public void run() {
+ long start = System.currentTimeMillis();
+ QueenPuzzle puzzle = new QueenPuzzle(29);
+ QueenPuzzleSolver solver = new QueenPuzzleSolver(puzzle);
+ List<Move> result = solver.solve();
+ long t = System.currentTimeMillis() - start;
+ time.addAndGet(t);
+ }
+
+ }
+
+ @Test
+ public void testConcurrentTime() throws InterruptedException {
+ for (int j = 24; j > 0; j--) {
+ ExecutorService exec = Executors.newFixedThreadPool(j);
+ final AtomicLong time = new AtomicLong(0);
+
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < 60; ++i) {
+ exec.submit(new Task(time));
+ }
+ exec.shutdown();
+ exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
+ long htime = System.currentTimeMillis() - start;
+ System.out.println(j + " thread total: " + time.get() + " htime "
+ + htime);
+ }
+ }
+
+}

0 comments on commit a388e4f

Please sign in to comment.