Java 并发编程实战学习笔记——路径查找类型并行任务的终止

来源:互联网 发布:centos ssh连接其他ip 编辑:程序博客网 时间:2024/06/05 16:29
1.该类问题的递归串行算法(深度优先遍历)

代码 复制 - 运行

package net.jcip.examples; import java.util.*; /**  * SequentialPuzzleSolver  * <p/>  * Sequential puzzle solver  *  * @author Brian Goetz and Tim Peierls  */ public class SequentialPuzzleSolver <P, M> {     private final Puzzle<P, M> puzzle;     private final Set<P> seen = new HashSet<P>();     public SequentialPuzzleSolver(Puzzle<P, M> puzzle) {         this.puzzle = puzzle;     }     public List<M> solve() {         P pos = puzzle.initialPosition();         return search(new PuzzleNode<P, M>(pos, null, null));     }     private List<M> search(PuzzleNode<P, M> node) {         if (!seen.contains(node.pos)) {             seen.add(node.pos);             if (puzzle.isGoal(node.pos))                 return node.asMoveList();             for (M move : puzzle.legalMoves(node.pos)) {                 P pos = puzzle.move(node.pos, move);                 PuzzleNode<P, M> child = new PuzzleNode<P, M>(pos, move, node);                 List<M> result = search(child);                 if (result != null)                     return result;             }         }         return null;     } } 

2.该类问题的并行算法(CountDownLatch 用作一个简单的开/关锁存器)
广度优先算法

代码 复制 - 运行

package net.jcip.examples; import java.util.concurrent.*; /**  * ValueLatch  * <p/>  * Result-bearing latch used by ConcurrentPuzzleSolver  *  * @author Brian Goetz and Tim Peierls  */ @ThreadSafe public class ValueLatch <T> {     @GuardedBy("this") private T value = null;     private final CountDownLatch done = new CountDownLatch(1);     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;         }     } } 

代码 复制 - 运行

package net.jcip.examples; import java.util.*; import java.util.concurrent.*; /**  * ConcurrentPuzzleSolver  * <p/>  * Concurrent version of puzzle solver  *  * @author Brian Goetz and Tim Peierls  */ public class ConcurrentPuzzleSolver <P, M> {     private final Puzzle<P, M> puzzle;     private final ExecutorService exec;     private final ConcurrentMap<P, Boolean> seen;     protected final ValueLatch<PuzzleNode<P, M>> solution = new ValueLatch<PuzzleNode<P, M>>();     public ConcurrentPuzzleSolver(Puzzle<P, M> puzzle) {         this.puzzle = puzzle;         this.exec = initThreadPool();         this.seen = new ConcurrentHashMap<P, Boolean>();         if (exec instanceof ThreadPoolExecutor) {             ThreadPoolExecutor tpe = (ThreadPoolExecutor) exec;             tpe.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());         }     }     private ExecutorService initThreadPool() {         return Executors.newCachedThreadPool();     }     public List<M> solve() throws InterruptedException {         try {             P p = puzzle.initialPosition();             exec.execute(newTask(p, null, null));             // block until solution found             PuzzleNode<P, M> solnPuzzleNode = solution.getValue();             return (solnPuzzleNode == null) ? null : solnPuzzleNode.asMoveList();         } finally {             exec.shutdown();         }     }     protected Runnable newTask(P p, M m, PuzzleNode<P, M> n) {         return new SolverTask(p, m, n);     }     protected class SolverTask extends PuzzleNode<P, M> implements Runnable {         SolverTask(P pos, M move, PuzzleNode<P, M> 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));         }     } } 


该段代码有个问题,就是不能够感知到该问题没有答案。
因此可以改为,可以感知到任务不存在的解决中

代码 复制 - 运行

package net.jcip.examples; import java.util.concurrent.atomic.*; /**  * PuzzleSolver  * <p/>  * Solver that recognizes when no solution exists  *  * @author Brian Goetz and Tim Peierls  */ public class PuzzleSolver <P,M> extends ConcurrentPuzzleSolver<P, M> {     PuzzleSolver(Puzzle<P, M> puzzle) {         super(puzzle);     }     private final AtomicInteger taskCount = new AtomicInteger(0);     protected Runnable newTask(P p, M m, PuzzleNode<P, M> n) {         return new CountingSolverTask(p, m, n);     }     class CountingSolverTask extends SolverTask {         CountingSolverTask(P pos, M move, PuzzleNode<P, M> prev) {             super(pos, move, prev);             taskCount.incrementAndGet();         }         public void run() {             try {                 super.run();             } finally {                 if (taskCount.decrementAndGet() == 0)                     solution.setValue(null);             }         }     } } 
原创粉丝点击