《Java多线程设计模式》助记笔记

来源:互联网 发布:java server 参数 编辑:程序博客网 时间:2024/05/16 17:55
导读:
  此书不难,起了一个“设计模式”的字眼是个嚎头。简单地把一些日常用到的小奇巧和《Concurrent Programming in Java》中的诸多内容重新描述了一下。现在花了2个小时把书上的内容简单抽象地记录一下,方便记忆。
  1.Singer Threaded Execution Pattern
  说明:
  使用synchronized关键字修饰unsafe method
  适用性:
  多线程
  数据可被多个线程访问的时候
  状态可能变化的时候
  需要确保安全性的时候(如:Collection集合类)
  补充:
  使用Collections的Wrapper方法
  进阶:
  关于synchronized:Before/After Pattern
  void method() {
  lock();
  try {
  ...
  } finally {
  unlock();
  }
  }
  原子操作:long与double并不是原子的,使用volatile关键字实现原子性
  2.Immutable Pattern
  说明:
  构建Immutable的参与者,如String,Integer等
  适用性:
  当实例产生后,状态不再变化
  实例需要共享且访问很频繁
  进阶:
  final类:无法继承
  final实例方法:无法被子类覆盖(实际被调用方法在运行时决定)
  final类方法:无法被子类隐藏(实际被调用方法在编译期决定)
  3.Guarded Suspension Pattern
  说明:
  不适合执行某个操作时,让执行该操作的线程等待(wait,notify,notifyAll)
  4.Balking Pattern
  说明:
  不适合执行某个操作时,让操作马上中断
  5.Producer-Consumer Pattern
  说明:
  在生产者和消费者之间建立一个通道,缓冲线程之间的处理速度差
  补充:
  当线程wait,进入等待区时,会把锁定解除。当对wait中的线程调用interrupt时,会先重新获取锁定,再抛出
  InterruptedException。获取锁定之前,无法抛出InterruptedException。
  补充:
  notify方法与interrupt方法
  notify/notifyAll是java.lang.Object类的方法,是该实例的等待区调用的。而不是对线程直接调用。notify/notifyAll方法所唤醒
  的线程,会前进到wait的下一个语句。另外,执行notify/notifyAll方法,需获取类的实例。
  interrupt是java.lang.Thread的方法,是对该线程直接调用的。当被interrupt的线程正在sleep或wait时,会抛出
  InterruptedException异常。执行interrupt(取消其它线程),不需要获取该线程的锁定。
  补充:
  isInterrupted方法用来检查指定线程的中断状态,他不会自己改变中断状态。
  Thread.interrupted方法会检查现在线程的中断状态,并清除它。当现在的线程为中断状态时返回true,否则返回false。
  6.Read-Write Lock Pattern
  说明:
  将读取与写入分开处理。在读取数据之前,必须获取读锁。而要写入时,必须获取写锁。可多个线程读取,但读取时不能写入。写入
  时不能读取和写入。
  锁定和解锁结构:
  前置处理(获取锁定)
  try {
  实际操作
  } finally {
  后续处理(解除锁定)
  }
  7.Thread-Per-Message Pattern
  说明:
  对每个命令或请求,分配一个线程,由这个线程执行。“委托消息的一端”和“执行消息的一端”是不同的线程。
  扩展提示:
  提升响应性,降低延迟时间
  适合在操作顺序无所谓时使用
  不需要返回值的适合
  应用在服务器的制作
  调用方法+启动线程 -> 传送消息
  8.Worker Thread Pattern
  说明:
  工人线程(Worker Thread)会依次抓一件工作来处理。当没有工作是,工人线程会停下来等待新的工作。工人线程存放在线程池中。
  扩展提示:
  invocation与execution的分离:
  提高响应性
  控制实行顺序
  可取消和可重复执行
  分散处理的第一步
  9.Future Pattern
  说明:
  获取Future参与者的线程,会在事后再去获取执行结果。如果已经有执行结果了,就可以马上拿到数据。如果执行结果还没有好,则
  等待到执行结果出现为止。在Future Pattern中,送出请求后,马上获取一个Future参与者类型的返回值。
  interface Data {
  public abstract String getContent();
  }
  class FutureData implements Data;?//当结果没有准备好时,wait(),否则返回RealData的getContent()。FutureData设置
  数据时,使用notifyAll()唤醒等待的线程
  class RealData implements Data;??//真实数据
  扩展提示:
  提升thoughtput
  异步方法调用的“返回值”
  分离“准备返回值”与“使用返回值”
  变形-不需要等待的Future参与者
  变形-会改变的Future参与者:在特定时刻返回特定的返回值
  10.Tow-Phase Termination Pattern
  说明:
  两阶段终止。进行平常作业中的线程,接收到终止请求时,并不会马上结束,而是进行必要的刷新工作,状态变为终止处理中,终止
  处理结束后,才真正结束线程。
  扩展提示:
  只检查标识是不够周全的。(需调用interrupt())
  只测试中断状态也是不够的(需使用标识)
  进行繁重的处理前,先检查终止请求
  使用join()和isAlive()检查指定线程是否结束
  使用addShutdownHook()在程序终止时进行处理
  11.Thread-Specific Storage Pattern
  说明:
  使用ThreadLocal,每个线程拥有自己的对象实例。
  扩展提示:
  放置线程特有信息的地方:
  1.线程外。ThreadLocal
  2.线程内。该Thread的实例字段
  12.Active Object Pattern
  说明:
  主动对象,不仅自己拥有独立的线程,还能够从外部接收异步信息,并能配合需要返回处理结果。
  客户端线程调用Proxy的某个方法,Proxy将该方法调用转换为生成一个Request对象,将此请求放进处理队列,并返回一个Future。
  SchedulerThread对象从队列取出Request并执行Request对象的execute()方法,此方法调用Servant对象执行具体的请求,并且返回RealData
  ,Request设置Future中的RealData,唤醒客户端线程,客户端线程从Future中取出请求结果。
  p.s Java线程机制是语言特性之一,对其它语言开发者来说,一些特殊之处(wait, notify等),本人不作任何解释。

本文转自
http://arbow.spaces.live.com/blog/cns!A25DE6AC7A5B029E!231.entry
原创粉丝点击