package net.jcip.examples; import java.util.*; import java.util.concurrent.*; /** * ConcurrentPuzzleSolver *
* Concurrent version of puzzle solver * * @author Brian Goetz and Tim Peierls */ public class ConcurrentPuzzleSolver{ private final Puzzle
puzzle; private final ExecutorService exec; private final ConcurrentMap
seen;
protected final ValueLatch puzzle) {
this.puzzle = puzzle;
this.exec = initThreadPool();
this.seen = new ConcurrentHashMap ();
if (exec instanceof ThreadPoolExecutor) {
ThreadPoolExecutor tpe = (ThreadPoolExecutor) exec;
tpe.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
}
}
private ExecutorService initThreadPool() {
return Executors.newCachedThreadPool();
}
public List solnPuzzleNode = solution.getValue();
return (solnPuzzleNode == null) ? null : solnPuzzleNode.asMoveList();
} finally {
exec.shutdown();
}
}
protected Runnable newTask(P p, M m, PuzzleNode n) {
return new SolverTask(p, m, n);
}
protected class SolverTask extends PuzzleNode implements Runnable {
SolverTask(P pos, M move, PuzzleNode prev) {
super(pos, move, prev);
}
public void run() {
if (solution.isSet()
|| seen.putIfAbsent(pos, true) != null)
return; // already solved or seen this position
if (puzzle.isGoal(pos))
solution.setValue(this);
else
for (M m : puzzle.legalMoves(pos))
exec.execute(newTask(puzzle.move(pos, m), m, this));
}
}
}