精华内容
下载资源
问答
  • 多线程设计模式

    千次阅读 2012-04-09 20:42:49
    多线程设计模式: 1.Single Threaded Execution Pattern  [同一时刻只允许一个线程操作]    比喻:三个挑水的和尚,只能同一时间一个人过桥,不然都掉河里喂鱼了。  总结:在多个线程同时要访问的方法上...

    多线程设计模式:
    1.Single Threaded Execution Pattern
       [同一时刻只允许一个线程操作]

        
       比喻:三个挑水的和尚,只能同一时间一个人过桥,不然都掉河里喂鱼了。
       总结:在多个线程同时要访问的方法上加上synchronized关键字。


    2.Immutable Pattern
       
    [变量赋值一次后只能读取,不能改变。]
       比喻:一夫多妻制,多个妻子共享一个丈夫。一旦赋值,任何一个妻子不能更改共享的 husband为其它人。
       总结:将多线程共享的变量用final关键字修饰。


    3.Guarded Suspension Pattern
       
    [要等到我准备好哦,没准备好就在门口等着,准备好了再叫你。]
       比喻:GG:小伙子去MM家,敲门...
            MM:我在换衣服,稍等。
            GG:等待[调用wait()方法挂起自己的线程]
            MM:换好了,进来吧[调用notify()或着notifyAll()方法通知GG]
       总结:判断某个条件是否为真,如果条件成立则继续执行一步,如果条件不成立用wait()方法挂起当前线程,条件为真后由另一个线程用notify()或 着notifyAll()方法唤醒挂起的线程。


    4.Balking Pattern
       [有人在做了?哈哈,太好了,我就不过去了!]

       比喻:饭店里我想好了要点的菜后,高高的举起手示意服务生过来,一个服务生准备过去的时候看到另外一个服务生已经过去了,哈哈已经有人过去了我就不过去了。
       总结:设置一个volatile的共享变量,多个线程进入同一方法时,判断变量的值是否为真,如果为真说明有人已经在做这个工作了,线程返回,反之将变量赋值为真并执行。
       
    5.Producer-Consumer Pattern
       [生产-消费者,你生产蛋榚我来吃。]

       比喻(1):一群猪围着猪食槽的一头,塞进几块玉米饼后,群猪争先恐后从食槽头抢,谁抢到谁吃。
       比喻(2):一群猪围着猪食槽的头和尾,塞进几块玉米饼后,群猪争先恐后从食槽头和食槽尾抢,谁抢到谁吃。
       总结:<1>生产者将生产出来的东西add(E e)到一个Queue,然后唤醒正在从Queue等东西的线程,用poll()方法从队列的头获取到东西,当Queue里的东西被取完,取东西的线程再次被挂起。
               <2>生产者将生产出来的东西放入(方法很多,有add(E e)、addFirst(E e)、addLast(E e)等)一个Deque,然后唤醒正在从Queue等东西的线程,线程从Deque的头和尾取东西,当Deque里的东西被取完,取东西的线程再次被挂起。


    6.Read-Write Lock Pattern
       [学生抄的时候,不允许老师擦掉黑板上的字。]

       比喻:老师在黑板上写了些字,下面的同学在拼命的抄,过会儿老师要写些新的字,写新字要擦掉原来的那些,问:都写完了么?如果都回答写完了,就擦掉原来的字写新的,如果还有一个回答没写完,就等待最后一个同学抄完再写。
       总结:Jdk1.5及以上有专门的读写锁实现
            java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
           java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
    7.Thread-Per-Message Pattern  
       [一任务一线程]

       总结:一个客人一个妞服务,好是好,可是天朝扫黄太厉害,现在狼多肉少哇,用线程池吧,轮流服务。


    8.Worker Thread Pattern
       [同Producer-Consumer Pattern]


    9.Future Pattern
       [给您一张提货单,下午来取。]

       比喻:
           李刚:大钞票一摔,来只大蛋榚!
           店员:对不起没这么大的,但现做,给您张单子,下午xx点来取。
           李刚:取货单??,上面都写了些啥?
                订单号:SB01
                 客户名:李刚
                 已付款:250
              取货时间:PM2:50
       
       总结:调用某个方法时,这个方法可能需要请求其它系统,这个过程比较耗时,为了提高客户的体验需要方法立即返回,过一段时间再查询结果。
              在程序里声明一个Hashmap,Key保存订单号,Value保存生产出的蛋榚,然后根据订单号取得对应的蛋榚。


    10.Two-Phase Termination Pattern
       [玩具收拾好,睡觉去]
       比喻:小孩子在玩具,到点了妈妈喊:别玩了,睡觉去!
       总结:一个线程在while(!isInterrupted()){..}循环中执行,另外一个线程判断某个条件达到后获得准备被结束线程的句柄,调用interrupt()
            设置线程的中断状态。
    11.Thread-Specific Storage Pattern
       [线程私有物品保管箱]

        总结:一个方法可能会被同一个线程访问多次,如果每访问一次就要声明一个数据库连接的Connection变量,则对程序的性能有影响。将Connection放在ThreadLocal里,这样每次访问就不必再产生一个Connection,同一个线程对应同一个Connection.


    12.Active Object[]

    传统上,所有的对象都是被动的代码段,对象中的代码是在对它发出方法调用的线程中执行的。也就是,调用线程(calling threads)被“借出”,以执行被动对象的方法。

      而主动对象却不一样。这些对象持有它们自己的线程(甚或多个线程),并将这个线程用于执行对它们的任何方法的调用。因而,如果你想象一个传统对象,在里面封装了一个线程(或多个线程),你就得到了一个主动对象。

      例如,设想对象“A”已在你的程序的main()函数中被实例化。当你的程序启动时,OS创建一个线程,以从main()函数开始执行。如果你调用对象A的任何方法,该线程将“流过”那个方法,并执行其中的代码。一旦执行完成,该线程返回调用该方法的点并继续它的执行。但是,如果”A”是主动对象,事情就不是这样了。在这种情况下,主线程不会被主动对象借用。相反,当”A”的方法被调用时,方法的执行发生在主动对象持有的线程中。另一种思考方法:如果调用的是被动对象的方法(常规对象),调用会阻塞(同步的);而另一方面,如果调用的是主动对象的方法,调用不会阻塞(异步的)。


     见http://www.kuqin.com/ace-2002-12/Part-One/Chapter-6.htm

    展开全文
  • 多线程设计模式之保护性暂停模式

    万次阅读 2020-09-14 14:56:30
    多线程设计模式之保护性暂停模式 定义 保护性暂停模式(Guarded Suspension Design Pattern):当线程在访问某个对象时,发现条件不满足时,就暂时挂起等待条件满足时再次访问。 如果某个结果需要在多线程之间传递,...

    多线程设计模式之保护性暂停模式

    定义

    保护性暂停模式(Guarded Suspension Design Pattern):当线程在访问某个对象时,发现条件不满足时,就暂时挂起等待条件满足时再次访问。

    如果某个结果需要在多线程之间传递,则可以让这些线程关联到一个对象GuardedObject,但是如果这个结果需要不断的从一个线程到另一个线程那么可以使用消息队列(生产者/消费者)

    Thread.join()、Future就采用了保护性暂停模式。

    简单实现

    package com.morris.concurrent.pattern.guardedsuspension.v2;
    
    public class GuardedObject<V> {
    
        private final Object lock = new Object();
    
        private V v;
    
        private boolean isFinished;
    
        public void set(V v) {
            synchronized (lock) {
                this.v = v;
                isFinished = true;
                lock.notifyAll();
            }
        }
    
        public V get() throws InterruptedException {
            synchronized (lock) {
                while (!isFinished) {
                    lock.wait();
                }
            }
            return v;
        }
    }
    

    超时实现

    public V get(long millis) {
        synchronized (lock) {
            while (!isFinished) {
                try {
                    lock.wait(millis);
                    break;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return v;
    }
    

    上面的超时实现有点小问题。

    分析:假如超时时间是5s,但是在第2s的时候别人把这个线程中断了但是此时还没有结果,那么这个线程就会进入下次循环继续等待5s,这样这个线程就等待7s了。

    最终实现如下:

    public V get(long millis) {
        long begin = System.currentTimeMillis(); // 等待开始时间
        long waitedTime = 0; // 等待了多长时间
        synchronized (lock) {
            while (!isFinished) {
                if(waitedTime >= millis) {
                    System.out.println("超时了,不等了");
                    break;
                }
                try {
                    lock.wait(millis - waitedTime); // 继续等待剩余时间
                    break;
                } catch (InterruptedException e) {
                    waitedTime = System.currentTimeMillis() - begin;
                    System.out.println("被中断了,等了" + waitedTime + "ms");
                }
            }
        }
        return v;
    }
    

    使用保护性暂停模式实现Future和Callable

    public interface Callable<T> {
        T call();
    }
    
    public interface Future<T> {
        T get();
    }
    
    public class FutureTask<T> implements Future<T> {
    
        private boolean isFinish;
    
        private T t;
    
        public synchronized void set(T t) {
            this.t = t;
            this.isFinish = true;
            this.notifyAll();
        }
    
        @Override
        public synchronized T get() {
            while (!isFinish) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return t;
        }
    }
    
    public abstract class Executors {
    
        public static <T> Future<T> newSingleThreadPool(Callable<T> callable) {
            FutureTask<T> future = new FutureTask<>();
            new Thread(()->{
                T t = callable.call();
                future.set(t);
            }).start();
            return future;
        }
    
    }
    
    展开全文
  • java多线程设计模式

    千次阅读 2016-12-23 09:26:48
    附件为 java多线程设计模式
    1 I/O处理比较花费时间,故把执行I/O处理和非IO处理的线程分开。CPU执行速度很快、而内存的写入、读取很慢,所以有关CPU和内存交互会降低指令的速度。
    2 start方法运行有2个步骤
    启动新的线程
    运行new对象的run方法
    3 所有线程结束,程序结束。  主线程可以先结束,但并不表示程序结束。
    4 一个线程已经获得锁定,其他线程都不能执行该实例的synchronized方法。
    5 wait set 线程休息区,当线程调用wait()方法时,线程自动进入wait set 区等待,直到被唤醒。
    6 wait notify notifyAll方法都是在锁定时调用,唤醒的线程重新等待锁。并且都有对象obj.wait(),否则默认this.wait()
    7 线程好坏评判标准
       安全性和生存性为必考虑
    安全性    ---不损坏对象
    生存性    ---进行必要处理 , 防止线程挂掉
    复用性    ---可在利用类
    性能      ---能快速、大量的进行处理
    吞吐量越大、响应性越快、容量越大,性能越好
    8 可能发生死锁的3个条件
    a、具有多个sharedResourse参与者,即共享资源
    b、线程锁定一个sharedSourse时,还没解除前就去锁定另一个sharedSourse.
    c、获取sharedSourse的顺序不固定
    只要破坏a b c中的任意一个条件,就可以避免死锁的发生。
    9 临界区的大小与执行性能
    获取锁定需要花时间
    线程冲突时必须等待
    10 有锁定时一定要记得解锁,中间不能有return 或是异常。
    11 要在线程中共享long 和 double 的字段,必须在synchronized中操作,或是声明成volatile
    12 Immutable Thread(不可变线程)
    字段为 final私有
    没有setter方法
      优点:不需要synchronized字段,频繁访问的情况下可以大大提高性能。
    13 被阻挡而等待
    等待
    while(!ready){
    wait();
    }


    唤醒
    ready=true;
    notify()/notifyAll()
    14 ReadWriteLock
    Read  Read    不冲突
    Read  Write   冲突
    Write  Write   冲突
    15 进程与线程的区别
    a 进程的内存是独立的、线程的内存是共享的

    16 interrupt() 方法会唤醒sleep/wait/join ,但会直接到catch语句,而不是运行其后面的语句。
    17 join()等待线程结束










    疑问:
    1 同一个类中,2个方法用了synchronized, 调用其中的一个方法,另一个方法也被锁住了?
    答:是










    1、多核、多CPU线程
    Lock
    lock.lockInterruptibly(),其实和lock.lock()效果一样,只有当调用interrupt()方法时,前面的会先运行catch里代码。
    Condition 
    Timer
    TimerTask
    Callable<V>
    2 WeakReference弱引用,防止内存泄露,将弱引用对象占用空间释放。
    3  Futrue<V>  FutrueTask<V>
    4 JAVA netive关键字
    native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。
    Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。
    5 public ThreadPoolExecutor(int corePoolSize,  
                                  int maximumPoolSize,  
                                  long keepAliveTime,  
                                  TimeUnit unit,  
                                  BlockingQueue<Runnable> workQueue,  
                                  ThreadFactory threadFactory,  
                                  RejectedExecutionHandler handler)
    a.当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。 
    b.当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行 
    c.当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务 
    d.当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理 
    e.当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程 
    f.当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭 
      





    展开全文
  • 多线程设计模式——最后总结

    千次阅读 2016-07-16 14:55:20
    多线程设计模式 最后总结

    这些都是根据我最近看的《Java实战指南多线程编程(设计模式篇)》所得整理。

    设计模式是什么 (个人理解)

    个人理解,设计模式就是对一些相对固定类型的问题的比较好的解决办法,简单来说就是代码版的兵法。
    因为是对固定的问题的研究,所以很多设计模式的想法是经过时间的磨练,一般都是比较优秀的。
    但是由于设计模式只是一个思想,而不是具体的行动,在学习的时候应该注重对思想的理解,因为具体的实现是和语言以及实现的问题相关的。

    多线程设计模式考虑的问题

    多线程设计模式主要是解决多线程设计当中的问题的,主要是以下几个问题:
    1. 不使用锁的情况下保证线程安全:不可变对象模式,线程特有存储模式,串行线程模式
    2. 优雅地停止线程:两阶段终止模式
    3. 线程写作:保护性暂挂模式,消费者生产者模式
    4. 提高并发性:承诺模式,主动对象模式,流水线模式
    5. 提高响应性:主仆模式,半同步半异步模式
    6. 较少资源消耗:线程池模式,串行线程封闭模式

    模式与模式之间的的关系

    设计模式不是鼓励的,一个设计模式往往和其他设计模式存在某些关联:一个模式可以解决另一个模式带来的问题;一个模式可以看做是另一个模式的特殊情况;几个模式可以组合解决一个大问题;几个模式都可以解决同一个问题,只是看具体情况具体选择哪个模式。

    总结

    这本《Java实战指南多线程编程(设计模式篇)》的阅读和理解暂时告一段落,但是对于多线程相关知识的学习、理解和应用还有很长的一段路要走。

    展开全文
  • Java多线程设计模式_清晰完整PDF版

    千次下载 热门讨论 2015-04-22 17:37:18
    Java多线程设计模式_清晰完整PDF版,带有源码。绝对的清晰版,并且内容完整。
  • 多线程设计模式 - Future模式

    千次阅读 2019-11-24 21:57:14
    一起来看看多线程设计模式中的Future模式吧~概述Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。这类似我们日常生活中的在线购物流程,带在...
  • 图解Java多线程设计模式

    千次阅读 2017-09-12 16:18:39
    图解Java多线程设计模式
  • 国内首部Java多线程设计模式原创作品《Java多线程编程实战指南(设计模式篇)》已由电子工业出版社出版。本书从理论到实战,用生活化的实例和通俗易懂的语言全面介绍Java多线程编程的"三十六计"——多线程设计模式
  • 架构师入门笔记四 初识多线程设计模式 这章讲解常用的并行设计模式,为后续的多线程打基础。常用的并行设计模式有:Future 模式、Master-Worker模式 和 生产者-消费者模式。其中生产者-消费者模式是最为经典的常用...
  • 来源于:《java多线程设计模式》一书  本例的类结构图: 2.Data类: package read.write.pattern; /** * 读者与写者共同要访问的数据类 * @author lxb * */ public class Data { private final char[] ...
  • 我们这里介绍的Producer-Consumer生产者-消费者模式是多线程设计模式中很著名的一个设计模式。说到生产者消费者问题,大部分人都不会陌生,OS课的经典问题,并且其本身就是一个计算机编程中常见的问题。对于它的应用...
  • 网络爬虫中的那些多线程设计模式

    千次阅读 2013-12-17 20:07:49
    前天跟师兄讨论问题,提到多线程,这些天做简历,也在回顾项目,忽然想到曾经写过网络爬虫中所用到的多线程,当时就顾写了,没有好好总结,只记得细节很多,学到的东西不少,今天就爬虫中涉及到的多线程设计模式做个...
  • 多线程设计模式(Future/Master-Worker)

    千次阅读 2017-04-05 22:37:00
    多线程设计模式并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的总结和抽象。与串行程序相比,并行程序的结构通常更为复杂。因此合理的使用并行模式在多线程开发中更具有意义,在这里主要介绍...
  • Thread Specific Storage(线程特有存储)模式
  • 模式名称Promise(承诺)模式
  • 这些都是根据我最近看的《Java实战指南多线程编程(设计模式篇)》所得整理。模式名称Guarded Suspension(保护性暂挂模式)模式面对的问题多线程编程中,往往将一个任务分解为不同的部分,将其交由不同的线程来执行...
  • Pipeline(流水线)模式
  • 《Java多线程设计模式》笔记(一)

    千次阅读 2012-08-31 18:13:06
    当年上学的时候看过《Java多线程设计模式》这本书,对书里的内容感觉是云里雾里,现在重看有种拨开云雾见天日的爽快。 有些多线程编码风格经常使用,有些是由JUC提供相应的实现。 这些是线程的基本介绍 ...
  • //key表示worker的名字,value表示线程执行对象 workerMap.put("worker" i,new Thread(worker)); } } //用于提交任务 public void submit(Task task){ this.taskQueue.add(task); } //执行方法,启动应用...
  • Producer-Consumer生产者消费者模式
  • 十一、流水线模式(Pipeline) 1、核心思想 将一个任务处理分解为若干个处理阶段,其中每个处理阶段的输出作为下一个处理阶段的输入,并且各个处理阶段都有相应的工作者线程去执行相应的计算。 2、评价: 充分...
  • 多线程设计模式之Master-worker模式

    千次阅读 2017-12-27 18:50:16
     * 主程序,创建初始化任务,开始任务,判断线程是否都执行完毕,获取结果  *  */ public class main { public static void main(String[] args) { master master = new master(3);//创建一个消息转发器master,...
  • 经典多线程设计模式(重要)

    千次阅读 2018-03-02 14:57:53
    一、Future模式思想:当service(Main方法模拟)请求一个数据的时候,可以先给他返回一个包装类(空壳,代理对象,未来data,FutureData)然后开一个线程去异步加载真实数据,这样当service收到FutrueData,就可以做...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 422,231
精华内容 168,892
关键字:

多线程的设计模式