多线程之六:并发设计模式

 

整理自炼数成金

源码连接:

什么是设计模式

    在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题 ,所提出的解决方案。

    架构模式 – MVC – 分层

    设计模式 – 提炼系统中的组件

    代码模式(成例 Idiom)

        – 低层次,与编码直接相关

        – 如DCL

不变模式

    一个类的内部状态创建后,在整个生命期间都不会发生变化时,就是不变类

    不变模式不需要同步

    代码示例:

[java] view plain copy

  1. public final class Product {  
  2.     //确保无子类  
  3.     private final String no;  
  4.     //私有属性,不会被其他对象获取  
  5.     private final String name;  
  6.     //final保证属性不会被2次赋值  
  7.     private final double price;  
  8.     //在创建对象时,必须指定数据  
  9.     public Product(String no, String name, double price) {   
  10.         super();  
  11.         //因为创建之后,无法进行修改  
  12.         this.no = no;  
  13.         this.name = name;  
  14.         this.price = price;  
  15.     }  
  16.     public String getNo() {  
  17.         return no;  
  18.     }  
  19.     public String getName() {  
  20.         return name;  
  21.     }  
  22.     public double getPrice() {  
  23.         return price;  
  24.     }  
  25. }  

 

        JDK中的不变类:

 

            java.lang.String

            java.lang.Boolean

            java.lang.Byte

            java.lang.Character

            java.lang.Double

            java.lang.Float

            java.lang.Integer

            java.lang.Long

            java.lang.Short

 

        Future模式

        核心思想

            异步调用

            主线程可以获取到目标线程的处理结果

        与join()的区别

            join():主线程需要阻塞直到目标线程执行结束

            Future:启动了目标线程之后主线程还可以继续其他操作,直到需要取目标线程的处理结果的时候才进行等待。

主要构造:

 

        代码示例:

[java] view plain copy

  1. public interface Data {  
  2.  public String getResult ();  
  3. }  
  4. public class FutureData implements Data {  
  5.  protected RealData realdata = null//FutureData是RealData的包装  
  6.  protected boolean isReady = false;  
  7.  public synchronized void setRealData(RealData realdata) {  
  8.      if (isReady) {  
  9.         return;  
  10.      }  
  11.      this.realdata = realdata;  
  12.      isReady = true;  
  13.      notifyAll(); //RealData已经被注入,通知getResult()  
  14.  }  
  15.  public synchronized String getResult() { //会等待RealData构造完成  
  16.      while (!isReady) {  
  17.          try {  
  18.             wait(); //一直等待,知道RealData被注入  
  19.          } catch (InterruptedException e) {  
  20.          }  
  21.      }  
  22.     return realdata.result; //由RealData实现  
  23.  }  
  24. }  
  25.   
  26. public class RealData implements Data {  
  27.  protected final String result;  
  28.  public RealData(String para) {  
  29.      //RealData的构造可能很慢,需要用户等待很久,这里使用sleep模拟  
  30.      StringBuffer sb=new StringBuffer();  
  31.      for (int i = 0; i < 10; i++) {  
  32.          sb.append(para);  
  33.          try {  
  34.             //这里使用sleep,代替一个很慢的操作过程  
  35.             Thread.sleep(100);  
  36.          } catch (InterruptedException e) {  
  37.          }  
  38.     }  
  39.     result =sb.toString();  
  40.  }  
  41.  public String getResult() {  
  42.      return result;  
  43.  }  
  44. }  
  45. public class Client {  
  46.  public Data request(final String queryStr) {  
  47.     final FutureData future = new FutureData();  
  48.     new Thread() {  
  49.         public void run() {// RealData的构建很慢,  
  50.             //所以在单独的线程中进行  
  51.             RealData realdata = new RealData(queryStr);  
  52.             future.setRealData(realdata);  
  53.         }  
  54.     }.start();  
  55.     return future; // FutureData会被立即返回  
  56.  }  
  57. }  
  58. public static void main(String[] args) {  
  59.  Client client = new Client();  
  60.  //这里会立即返回,因为得到的是FutureData而不是RealData  
  61.  Data data = client.request("name");  
  62.  System.out.println("请求完毕");  
  63.  try {  
  64.      //这里可以用一个sleep代替了对其他业务逻辑的处理  
  65.      //在处理这些业务逻辑的过程中,RealData被创建,从而充分利用了等待时间  
  66.      Thread.sleep(2000);  
  67.  } catch (InterruptedException e) {  
  68.  }  
  69.  //使用真实的数据,数据如果没准备好,这里会进行阻塞  
  70.  System.out.println("数据 = " + data.getResult());  
  71. }  

 

        JDK对Future模式的支持

 

        多线程之六:并发设计模式_第1张图片

            代码示例:

[java] view plain copy

  1. public class RealData implements Callable {  
  2.     private String para;  
  3.     public RealData(String para){  
  4.         this.para=para;  
  5.     }  
  6.     @Override  
  7.     public String call() throws Exception {  
  8.         StringBuffer sb=new StringBuffer();  
  9.         for (int i = 0; i < 10; i++) {  
  10.             sb.append(para);  
  11.             try {  
  12.                 Thread.sleep(100);  
  13.             } catch (InterruptedException e) {  
  14.             }  
  15.         }  
  16.         return sb.toString();  
  17.     }  
  18. }  
  19.     public class FutureMain {  
  20.     public static void main(String[] args) throws InterruptedException, ExecutionException {  
  21.         //构造FutureTask  
  22.         FutureTask future = new FutureTask(new RealData("a"));  
  23.         ExecutorService executor = Executors.newFixedThreadPool(1);  
  24.         //执行FutureTask,相当于上例中的 client.request("a") 发送请求  
  25.         //在这里开启线程进行RealData的call()执行  
  26.         executor.submit(future);  
  27.   
  28.         System.out.println("请求完毕");  
  29.         try {  
  30.             //这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理  
  31.             Thread.sleep(2000);  
  32.         } catch (InterruptedException e) {  
  33.         }  
  34.         //相当于data.getResult (),取得call()方法的返回值  
  35.         //如果此时call()方法没有执行完成,则依然会等待  
  36.         System.out.println("数据 = " + future.get());  
  37.     }  
  38. }  
  39. public class FutureMain2 {  
  40.  public static void main(String[] args) throws InterruptedException, ExecutionException {  
  41.   
  42.      ExecutorService executor = Executors.newFixedThreadPool(1);  
  43.      //执行FutureTask,相当于上例中的 client.request("a") 发送请求  
  44.      //在这里开启线程进行RealData的call()执行  
  45.      Future future=executor.submit(new RealData("a"));  
  46.      System.out.println("请求完毕");  
  47.      try {  
  48.          //这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理  
  49.          Thread.sleep(2000);  
  50.      } catch (InterruptedException e) {  
  51.      }  
  52.      //相当于data.getResult (),取得call()方法的返回值  
  53.      //如果此时call()方法没有执行完成,则依然会等待  
  54.      System.out.println("数据 = " + future.get());  
  55.  }  
  56. }  

 

生产者消费者

 

    生产者-消费者模式是一个经典的多线程设计模式。它为多线程间的协作提供了良好的解决方案。 在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程。生产者线 程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务。生产者和消费者之间则通 过共享内存缓冲区进行通信。

    主要角色:

    多线程之六:并发设计模式_第2张图片

    类图:

     多线程之六:并发设计模式_第3张图片

你可能感兴趣的:(Java)