Java 并发编程实战学习笔记——路径查找类型并行任务的终止
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);
}
}
}
}
Java 并发编程实战学习笔记——路径查找类型并行任务的终止的更多相关文章
- java并发编程实战学习(3)--基础构建模块
转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...
- 《java并发编程实战》笔记
<java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为: Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...
- Java并发编程实战 读书笔记(一)
最近在看多线程经典书籍Java并发变成实战,很多概念有疑惑,虽然工作中很少用到多线程,但觉得还是自己太弱了.加油.记一些随笔.下面简单介绍一下线程. 一 线程与进程 进程与线程的解释 个人觉 ...
- Java并发编程实战 读书笔记(二)
关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...
- 《Java并发编程实战》笔记-非阻塞算法
如果在某种算法中,一个线程的失败或挂起不会导致其他线程也失败和挂起,那么这种算法就被称为非阻塞算法.如果在算法的每个步骤中都存在某个线程能够执行下去,那么这种算法也被称为无锁(Lock-Free)算法 ...
- 《Java并发编程的艺术》第4章 Java并发编程基础 ——学习笔记
参考https://www.cnblogs.com/lilinzhiyu/p/8086235.html 4.1 线程简介 进程:操作系统在运行一个程序时,会为其创建一个进程. 线程:是进程的一个执行单 ...
- 《Java并发编程实战》笔记-Happens-Before规则
Happens-Before规则 程序顺序规则.如果程序中操作A在操作B之前,那么在线程中A操作将在B操作之前执行. 监视器锁规则.在监视器锁上的解锁操作必须在同一个监视器锁上的加锁操作之前执行. v ...
- 《Java并发编程实战》笔记-锁与原子变量性能比较
如果线程本地的计算量较少,那么在锁和原子变量上的竞争将非常激烈.如果线程本地的计算量较多,那么在锁和原子变量上的竞争会降低,因为在线程中访问锁和原子变量的频率将降低. 在高度竞争的情况下,锁的性能将超 ...
- 《Java并发编程实战》笔记-OneValueCache与原子引用技术
/** * NumberRange * <p/> * Number range class that does not sufficiently protect its invariant ...
- 《Java并发编程实战》笔记-状态依赖方法的标准形式
void stateDependentMethod() throws InterruptedException { //必须通过一个锁来保护条件谓词 synchronized(lock) { whil ...
随机推荐
- Docker学习11-Docker常规方式安装软件
本文咱们将通过按照Tomcat.按照MySQL.安装Redis这三个实战安装,来熟悉在docker中怎么安装软件,咱们使用端口映射,及数据卷的使用场景 安装的总体步骤: 1:搜索镜像: 2:拉取镜像: ...
- Web 国际化:新增越南语语系(vue i18n)
前提: 1. 在src/locales文件夹中,新增vi.json文件 背景: 1. vue 步骤: 1. 在main.js中, import VueI18n from 'vue-i18n' Vue. ...
- hook拼多多客服软件发消息,拼多多客服机器人代码,拼多多发消息代码
最近由于工作需要,逆向了拼多多客服平台,能调用消息监听.消息发送.根据订单号发起会话,是纯hook实现的,demo包括c++调用demo,c#调用demo.hook 的dll是c++编写的,有需要的人 ...
- 掌握 C++17:结构化绑定与拷贝消除的妙用
C++17 特性示例 1. 结构化绑定(Structured Binding) 结构化绑定允许你用一个对象的元素或成员同时实例化多个实体. 结构化绑定允许你在声明变量的同时解构一个复合类型的数据结构( ...
- TypeScript – 冷知识
当 generic return 遇上 parameter 报错了.原因是 querySelector 默认返回类型是抽象的 Element. 而 method 参数要求的是具体的 InputElem ...
- HTML & CSS – Responsive Image 响应式图片 (完整版)
前言 之前就有写过关于 Retina 和 Responsive Image 响应式图片 (responsive image) Retina 显示屏 但写的太烂了, 所以有了后来的 屏幕, 打印, 分辨 ...
- SQL server temporal table 学习笔记
refer: https://blog.csdn.net/Hehuyi_In/article/details/89670462 https://docs.microsoft.com/en-us/sql ...
- 架构与思维:漫谈高并发业务的CAS及ABA
1 高并发场景下的难题 1.1 典型支付场景 这是最经典的场景.支付过程,要先查询买家的账户余额,然后计算商品价格,最后对买家进行进行扣款,像这类的分布式操作, 如果是并发量低的情况下完全没有问题的, ...
- Kulla-Conty BRDF
question: brdf中的几何因子考虑了微表面的自遮挡,当表面粗糙度较大或者与法线夹角越大时,这个因子越小,导致颜色越暗.这部分能量相等于直接忽略掉了,实际上被遮挡的光线会被反射,然后经过若干次 ...
- C# Webapi Filter 过滤器 - 生命周期钩子函数 - Action Filter 基础
ACTION Filter IAsyncACtionFilter 接口 : 1.注入ActionFilter // 注册过滤器 builder.Services.Configure<MvcOpt ...