Upload
tony-deng
View
2.118
Download
9
Embed Size (px)
DESCRIPTION
Citation preview
JAVA 多线程设计模式
by 李学科
热身 : 非线程安全的原子操作• 线程 1:longNum=123L• 线程 2:longNum=456L• 结果 :– longNum=123L– longNum=456L– longNum=0L– longNum=31415926L
• 原因 :long 和 double 是 64 位的 , 在不同的系统中有可能被拆成两个 32 位来运算
SingleThreadedExecution
• 角色 :– 资源使用者– 共享资源:被多个线程访问的对象• 安全方法• 非安全方法——使用 synchronized 加以保护
• 死锁的前提– 有多个共享资源– 在一个资源未释放的情况下,去锁定另一个资源– 获取共享资源的顺序不固定
SingleThreadedExecution
public class Gate { private String people= "Nobody"; private String address = "Nowhere"; public synchronized void pass(String people) { // 只有一个人通过这扇门 } public String getGateName() { // }}
Immutable
• 典型代表 :String 类• 例子 :
public final class Person { private final String name; //no setter public Person(String name) { this.name = name;
} public String getName() { return name; }}
Immutable
• 特点 :– 不需要 synchronized 保护– 高效
• 使用场景 :– 实例产生后 , 状态不再发生变化– 实例需要共享 , 且访问频繁
• 设计思想 :String 和 StringBuffer– 可变和不变解耦– 二者可互相切换
GuardedSuspension
GuardedSuspensionpublic synchronized Request getRequest() {
while (queue.size() <= 0) { //guard condition try { wait(); } catch (InterruptedException e) { } } return (Request)queue.removeFirst(); } public synchronized void putRequest(Request request) { queue.addLast(request); notifyAll(); }
GuardedSuspension
• 升级版的 SingleThreadedExecution• 有一个保护的对象• 不满足警戒条件则等待• 提供可以通过警戒条件的方法
Balking
Balkingpublic class Data { private boolean changed; public synchronized void change(String newContent) { content = newContent; changed = true; } public synchronized void save() throws IOException { if (!changed) {// 内容没有变化 , 返回
return; } doSave(); // 实际资料储存到挡案里用的方法 changed = false; } }
Balking
• 使用场景– 不需要刻意执行 (doSave)– 不想等待警戒条件变化– 警戒条件只有第一次成立 , 如下private boolean done;public synchronized void init(){
if (done) {return;
}doInit();done=true;
}
在 Balking 与 GuardedSuspension 之间—— timeout
• wait 何时结束– 当 notify 方法执行时– 当 notifyAll 方法执行时– 当 interrupt 方法执行时– 当 timeout 时
• synchronized 没有 timeout, 也不能中断 ( 死锁 )
ProducerConsumer
厨 师
+桌子
桌 子
+put()+take()
顾 客
+桌子
桌 子 上 的 蛋 糕
放蛋糕
做
+拿蛋糕
吃
ProducerConsumer
ProducerConsumerpublic class Table { private final String[] buffer; private int count; // buffer 内的蛋糕数 public synchronized void put(String cake) throws InterruptedException { while (count >= buffer.length) { wait(); }
// 加一块蛋糕 notifyAll(); } public synchronized String take() throws InterruptedException { while (count <= 0) {wait(); } notifyAll();
return cake; // 减一块蛋糕 }}
ProducerConsumer
• 设计思想– 线程安全部分的解耦– 生产者和消费者的快速响应– 可以给缓冲区数据安排顺序– 考虑缓冲区的负荷
Thread-Per-Message
private final Helper helper = new Helper(); public void request(final int p1, final char p2) { new Thread() { public void run() { helper.handle(p1, p2); } }.start(); }
Thread-Per-Message
• 特点– 提升响应性 , 降低延迟时间– 对操作顺序无要求– 不需要返回值
调用与执行分离• 提高响应性:如果执行时间长,调用的操
作受牵连• 控制顺序:如果不分离,谁先调用先执行,
分离后,执行顺序变得可控• 可取消和可重复执行:在调用和执行的时
间差内,可以取消。调用后,产生工作的实例,可以针对一份工作,多次执行
• 可分布式处理
Future
FutureData
+realData
+setRealData()+getContent()
FutureCreater
+create()
RealData
+content
+getContent()
Data<<interface>>
create
create
Client
+data
user
getContent
Futurepublic Data create(final int param1, final char param1) {
// (1) 建立 FutureData 的实体 final FutureData future = new FutureData(); // (2) 为了建立 RealData 的实体,启动新的线程 new Thread() { public void run() { RealData realdata = new RealData(param1, param2); future.setRealData(realdata); } }.start(); // (3) 返回 FutureData 实体 return future; }
Future
public class RealData implements Data { private final String content; public RealData(int param1, char param2) {
//do something, burn timethis.content = new String(buffer);
} public String getContent() { return content; }}
Futurepublic class FutureData implements Data { private RealData realdata = null; private boolean ready = false; public synchronized void setRealData(RealData realdata) { if (ready) return; // balking this.realdata = realdata; this.ready = true; notifyAll(); } public synchronized String getContent() { while (!ready) { //garded try { wait(); } catch (InterruptedException e) { } } return realdata.getContent(); }}
Callback 与 FutureCallback Future
使用数据 Client 不关注何时使用数据
Client 明确的知道使用数据时间
线程安全 回调函数需要考虑线程安全问题
只有 FutureData 需要考虑线程安全
Future
• 特点– 使用数据和准备数据的分离
• Thinking– 数据有多种状态 ?– FutureCreater 的安全性– Future 模式一定会提高效率吗 ?
つづく
选修
《Matrix》前传+番外篇
Animatrix
Animatrix
• 名字由来 : 通常, Ani 是英文单词“动画animation” 的缩写,但在这里,它却代表着日文中的“动漫 anime” 。
• 《黑客帝国动画版》由 9段以《黑客帝国》系列电影世界观为基础生发出的短片组成,各篇的角度与风格各异,制作班底汇聚了日本、美国、韩国三地的动画精英。
The Final Flight of the Osiris
• 剧本:沃卓斯基兄弟 • 导演:安迪 ·琼斯 Andy Jones( 《最终幻
想》 ) • 动画设计与制作: SQUARE公司 • 片长: 11:00
The Final Flight of the Osiris
The Second Renaissance
• 剧本:沃卓斯基兄弟• 导演:前田真宏 ( 《青之 6号》 ) • 动画设计与制作:摄氏 4度工作室,东京• 片长: 8:23
The Second Renaissance
The Second Renaissance
Beyond
• 剧本 /导演:森本晃司• 动画设计与制作:摄氏 4度工作室,东京 • 片长: 12:48 • 内容简要:在一栋神秘的大楼里,似乎各
种不可思议的事情都可发生,它究竟有什么秘密?这是不是通往真实世界的出口?MATRIX密探们当然不会就此忽视,他们要极力修补这个漏洞……
Beyond
Beyond