整理自炼数成金
源码连接:
什么是设计模式在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题 ,所提出的解决方案。
架构模式 – MVC – 分层
设计模式 – 提炼系统中的组件
代码模式(成例 Idiom)
– 低层次,与编码直接相关
– 如DCL
不变模式
一个类的内部状态创建后,在整个生命期间都不会发生变化时,就是不变类
不变模式不需要同步
代码示例:
- public final class Product {
- //确保无子类
- private final String no;
- //私有属性,不会被其他对象获取
- private final String name;
- //final保证属性不会被2次赋值
- private final double price;
- //在创建对象时,必须指定数据
- public Product(String no, String name, double price) {
- super();
- //因为创建之后,无法进行修改
- this.no = no;
- this.name = name;
- this.price = price;
- }
- public String getNo() {
- return no;
- }
- public String getName() {
- return name;
- }
- public double getPrice() {
- return price;
- }
- }
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:启动了目标线程之后主线程还可以继续其他操作,直到需要取目标线程的处理结果的时候才进行等待。
主要构造:
代码示例:
- public interface Data {
- public String getResult ();
- }
- public class FutureData implements Data {
- protected RealData realdata = null; //FutureData是RealData的包装
- protected boolean isReady = false;
- public synchronized void setRealData(RealData realdata) {
- if (isReady) {
- return;
- }
- this.realdata = realdata;
- isReady = true;
- notifyAll(); //RealData已经被注入,通知getResult()
- }
- public synchronized String getResult() { //会等待RealData构造完成
- while (!isReady) {
- try {
- wait(); //一直等待,知道RealData被注入
- } catch (InterruptedException e) {
- }
- }
- return realdata.result; //由RealData实现
- }
- }
- public class RealData implements Data {
- protected final String result;
- public RealData(String para) {
- //RealData的构造可能很慢,需要用户等待很久,这里使用sleep模拟
- StringBuffer sb=new StringBuffer();
- for (int i = 0; i < 10; i++) {
- sb.append(para);
- try {
- //这里使用sleep,代替一个很慢的操作过程
- Thread.sleep(100);
- } catch (InterruptedException e) {
- }
- }
- result =sb.toString();
- }
- public String getResult() {
- return result;
- }
- }
- public class Client {
- public Data request(final String queryStr) {
- final FutureData future = new FutureData();
- new Thread() {
- public void run() {// RealData的构建很慢,
- //所以在单独的线程中进行
- RealData realdata = new RealData(queryStr);
- future.setRealData(realdata);
- }
- }.start();
- return future; // FutureData会被立即返回
- }
- }
- public static void main(String[] args) {
- Client client = new Client();
- //这里会立即返回,因为得到的是FutureData而不是RealData
- Data data = client.request("name");
- System.out.println("请求完毕");
- try {
- //这里可以用一个sleep代替了对其他业务逻辑的处理
- //在处理这些业务逻辑的过程中,RealData被创建,从而充分利用了等待时间
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- }
- //使用真实的数据,数据如果没准备好,这里会进行阻塞
- System.out.println("数据 = " + data.getResult());
- }
JDK对Future模式的支持
代码示例:
- public class RealData implements Callable<String> {
- private String para;
- public RealData(String para){
- this.para=para;
- }
- @Override
- public String call() throws Exception {
- StringBuffer sb=new StringBuffer();
- for (int i = 0; i < 10; i++) {
- sb.append(para);
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- }
- }
- return sb.toString();
- }
- }
- public class FutureMain {
- public static void main(String[] args) throws InterruptedException, ExecutionException {
- //构造FutureTask
- FutureTask<String> future = new FutureTask<String>(new RealData("a"));
- ExecutorService executor = Executors.newFixedThreadPool(1);
- //执行FutureTask,相当于上例中的 client.request("a") 发送请求
- //在这里开启线程进行RealData的call()执行
- executor.submit(future);
- System.out.println("请求完毕");
- try {
- //这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- }
- //相当于data.getResult (),取得call()方法的返回值
- //如果此时call()方法没有执行完成,则依然会等待
- System.out.println("数据 = " + future.get());
- }
- }
- public class FutureMain2 {
- public static void main(String[] args) throws InterruptedException, ExecutionException {
- ExecutorService executor = Executors.newFixedThreadPool(1);
- //执行FutureTask,相当于上例中的 client.request("a") 发送请求
- //在这里开启线程进行RealData的call()执行
- Future<String> future=executor.submit(new RealData("a"));
- System.out.println("请求完毕");
- try {
- //这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- }
- //相当于data.getResult (),取得call()方法的返回值
- //如果此时call()方法没有执行完成,则依然会等待
- System.out.println("数据 = " + future.get());
- }
- }
生产者消费者
生产者-消费者模式是一个经典的多线程设计模式。它为多线程间的协作提供了良好的解决方案。 在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程。生产者线 程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务。生产者和消费者之间则通 过共享内存缓冲区进行通信。
主要角色:
类图: