多线程设计模式(翻译以供学习之用,决不侵犯版权之念)

 

图有问题,可以直接看sina的博客:http://blog.sina.com.cn/s/blog_75bf9017010133d3.html

什么是模式(patter):

  • 对重复发生的问题的可重用解决方案
  • 和面向对象设计有关(我不是很明白这一点,想必应该是和文章本身所描述的主体有关系吧。从设计模式本身讲,虽然绝大部分都和面向对象有关系,但是这种关系应该是外在的,也就是说不是必然的。)
  • 模式可以和其它主题有关系(分析,编码,测试,。。。)

对模式描写的结构为:

  • 简述
  • 上下文环境(问题详述)
  • forces
  • 解决方案
  • consequences
  • 相关模式

竞争:竞争是一种情况,它的输出依赖于并行操作的执行顺序(原文定义为并行操作的结束顺序,但是很明显,完整的说不仅仅是结束时顺序有关系,除非仅仅是在结束的时候会去访问和修改共享资源。)

 

单线程模式:单线程模式的实现对于所有有可能进行并发调用的方法进行了同步(文章中叫做concurrency=garded)。并且声明大部分其它并发模式都使用了单线程执行模式。

 

    1. 监视暂停(guarded suspecsion)

 

简述:当一个条件出现而停止了一个方法的执行,停止该方法的执行直到该条件不再存在

问题详述:一个像下面显示的类

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第1张图片
push()和pull()都已经做了同步。pull()在队列空时不会返回,而是等待队列中重新出现元素。pash()却需要先拿到锁才可以向队列中插入元素。因此,push()和pull()可能造成死锁。

 

按照书中的做法,使用wait and notify模式:

class Widget{

    synchronized void foo() {

        while (!isOK()) {

            wait();

        }
    }

 

    synchronized void bar (x int) {

        ..

        notify();

    }

}

有关于这个例子我自己觉得有点不清楚。我的理解是这样的,作者的意思是去除掉Queue中的同步调用,而改用Widget做同步的控制。再看下面的叙述:当主观的选择一个线程执行notify操作不是一个好方法时,可以执行notifyAll的方法来通知所有正在等待的线程。在这里不免有一个疑问,foo()方法的同步要求是否应该加到wait()方法内部,这样才可以保证notify()或者notifyAll()得到调用。

 

    2. 阻挡(balking)

 

简介:如果一个对象的方法在该对象的不合适状态被调用,该方法直接返回而不执行任何操作。

这是该文档中所贴的图片:

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第2张图片
Balking模式的意义在于很多场景下,如果两个线程可能竞争资源,但其实它们并不希望仍然执行一个操作,加入它发现另一个线程已经取得了该资源并且正在执行它想执行的操作。Balking的场景正是为此而设计的。

 

    3. 调度者(Scheduler)

 

简介:控制被调度的线程的执行顺序来执行单线程环境中的代码。调度者模式提供了一种执行调度的策略。它独立于任何其它的调度策略。

 

适用情况:多个线程在相同的时间试图访问共同的资源,但是只有一个线程可以访问。程序的需求暗示了线程应该按照一定的顺序访问共享资源。

 

两种解决方案:

1.

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第3张图片

2.

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第4张图片
在一些应用中,调度策略不需要调度者询问需求对象。一个这样的策略是允许进入方法的调用返回它们被调用的顺序。另一个这类策略不强制请求被调度,但是需要一个任务的结束和另一个任务的开始之间间隔5分钟。

 

优缺点:调度者模式提供一种方法明确控制线程可能执行的顺序; 调度策略封装在自己的类中并且可以重用;使用调度者模式需要比一般同步方法更长的时间。

 

和其他模式的关系:一般会使用读写锁来保证调度的公平性


    4. 读写锁

 

简介: 允许并发读操作,但是需要排他的写操作

 

使用情况:

需要对一个对象的状态进行读写

多个读操作可以同时进行;读操作而已保证返回正确的结果如果当时没有写操作

写操作在同一个时刻只能有一个在进行

可能会有同时初始的读写操作

允许同时初始化的读操作以提高响应速度和吞吐量

读和写调度的逻辑应该可以重用

 

解决方案:

1.

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第5张图片

读写锁的优缺点:

对一个对象的set操作不破坏其他的set操作或者get操作

如果有比较多的对一个对象的get操作的同步调用,读写锁会比单独进程模式取得更好的性能

如果有比较少的对一个队形的get操作的同步调用,读写锁可能比单独线程模式取得更差的性能

调度的策略可能会引起饥渴或者写饥渴

 

和其他模式的关系:

独立线程模式在大多数访问都是写操作时是读写锁的一个很好的代替者

读写锁模式是调度模式的一个特例

 

    4. 生产者和消费者

 

简介: 协调异步的信息或者对象的生产者和消费者

 

解决方案:

1. 多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第6张图片

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第7张图片

和其他模式的关系:

可以使用监视暂停模式管理一个消费者对象的状态来从一个空的队列中获取一个对象

生产消费者模式可以看做调度模式的一种特例: 策略基于资源的可用性;调度者将一个资源分配给一个线程,但是当那个线程结束时不在要求对资源的控制权。

 

    5. 两阶段终结(two phase termination)

 

简介: 通过对一个栓的设置来有序的关闭一个线程或者一个进程

 

解决方案:

多线程设计模式(翻译以供学习之用,决不侵犯版权之念)_第8张图片

优缺点:

允许线程或者进程在终止前完成清理工作;会延长线程和进程的终止时间

 

注:完全是翻译和转载,版权归Mark Grand所有

你可能感兴趣的:(多线程设计模式(翻译以供学习之用,决不侵犯版权之念))