博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
责任链模式的两种实现
阅读量:7067 次
发布时间:2019-06-28

本文共 5300 字,大约阅读时间需要 17 分钟。

实现一:servlet 经典模式

图片描述

该模式特点:多线程环境环境下,需要每一个客户端请求,new 一个ConcreteFilterChain对象。如果对象太大,增加cpu和gc的负担。

代码demo

import java.io.IOException;public interface Filter {    public void doFilter(Context ctx, FilterChain chain) throws IOException;}
import java.io.IOException;public interface FilterChain {    void doFilter(Context ctx) throws IOException;}
import java.io.IOException;public class PrintOne implements Filter {    @Override    public void doFilter(Context ctx, FilterChain chain) throws IOException {        System.out.println(Thread.currentThread().getId()+ " 1");        chain.doFilter(ctx);    }}import java.io.IOException;public class PrintTwo implements Filter {    @Override    public void doFilter(Context ctx, FilterChain chain) throws IOException {        System.out.println(Thread.currentThread().getId()+" 2");        chain.doFilter(ctx);    }}import java.io.IOException;public class PrintThree implements Filter {    @Override    public void doFilter(Context ctx, FilterChain chain) throws IOException {        System.out.println(Thread.currentThread().getId()+" 3");        chain.doFilter(ctx);    }}
import java.io.IOException;import java.util.List;public class DefaultFilterChain implements FilterChain {    public DefaultFilterChain(List
list) { this.list = list; } List
list; int pos = 0; @Override public void doFilter(Context ctx) throws IOException { if(pos < list.size()){ Filter filter = list.get(pos); pos++; filter.doFilter(ctx,this); } }}

测试程序

import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class TestMain {    static ExecutorService executorService = Executors.newFixedThreadPool(5);    public static void main(String args[]){        List
list = new ArrayList
(); list.add(new PrintOne()); list.add(new PrintTwo()); list.add(new PrintThree()); FilterChain filterChain = new DefaultFilterChain(list); for(int i=0;i<2;i++) { executorService.submit(new Event(filterChain)); } } public static class Event implements Runnable{ public Event(FilterChain filterChain) { this.filterChain = filterChain; } FilterChain filterChain; @Override public void run() { Context ctx = new Context(); try { filterChain.doFilter(ctx); } catch (IOException e) { e.printStackTrace(); } } }}

注意:该测试程序是有bug的,多线程共享filterChain会导致filter的游标定位错误。要解决这个问题,要么每个请求new一个DefaultFilterChain对象。

实现二

参考netty pipeline的实现

图片描述

该实现的优点:多线程环境下,不需要每一个客户的请求都new一个DefaultFilterChain.该算法的巧妙之处在于:将handler跟filterchain 组成成一个节点。 通过handler驱动节点的扭转

上代码

public class Context {}public interface Handler {    void handle(Context ctx,FilterChain filterChain);}public class PrintOne implements Handler {    @Override    public void handle(Context ctx, FilterChain filterChain) {        System.out.println(Thread.currentThread().getId()+" 1");        filterChain.fireNext(ctx);    }}public class PrintTwo implements Handler{    @Override    public void handle(Context ctx, FilterChain filterChain) {        System.out.println(Thread.currentThread().getId()+" 2");        filterChain.fireNext(ctx);    }}public class PrintThree implements Handler {    @Override    public void handle(Context ctx, FilterChain filterChain) {        System.out.println(Thread.currentThread().getId()+" 3");        filterChain.fireNext(ctx);    }}

FilterChain和DefaultFilterChain

public interface FilterChain {    void handler(Context ctx);    void fireNext(Context ctx);}public class DefaultFilterChain implements FilterChain {    private FilterChain next;    private Handler handler;    public DefaultFilterChain(FilterChain next, Handler handler) {        this.next = next;        this.handler = handler;    }    @Override    public void handler(Context ctx) {        handler.handle(ctx,this);    }    public void fireNext(Context ctx){        FilterChain next_ = this.next;        if(next_ != null){            next_ .handler(ctx);        }    }}

测试代码

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class FilterChainTest {    static ExecutorService executorService = Executors.newFixedThreadPool(3);    public static void main(String args[]){        Handler h1 = new PrintOne();        Handler h2 = new PrintTwo();        Handler h3 = new PrintThree();        FilterChain filterChain3 = new DefaultFilterChain(null,h3);        FilterChain filterChain2 = new DefaultFilterChain(filterChain3,h2);        FilterChain filterChain1 = new DefaultFilterChain(filterChain2,h1);        Context ctx = new Context();        for(int i=0;i<3;i++){            executorService.execute(new RunPrintEcho(filterChain1,ctx));        }    }    public static class RunPrintEcho implements Runnable{        FilterChain filterChain;        Context ctx;        public RunPrintEcho(FilterChain filterChain, Context ctx) {            this.filterChain = filterChain;            this.ctx = ctx;        }        @Override        public void run() {            filterChain.handler(this.ctx);        }    }}

大功告成!

转载地址:http://jwall.baihongyu.com/

你可能感兴趣的文章
java通过文件名运行_Java 从返回文件名获取内容类型
查看>>
java中双精度型变量_java中的基本数据类型
查看>>
java运行csh文件_Java,Prel,Csh界面
查看>>
php xmp,xmp1和2模式区别有哪些
查看>>
java随机矩阵,Spark-RSVD:Spark大型稀疏矩阵随机奇异值分解库
查看>>
php++简单左侧导航,简单的jquery左侧导航栏和页面选中效果_jquery
查看>>
29岁零基础学php,零基础学PHP,从入门到精通
查看>>
真因数之和编程matlab,真因数
查看>>
php 车牌号,总结关于车牌注意点
查看>>
运动方向估计的管道滤波matlab,基于运动方向估计的管道滤波算法
查看>>
java基础看完,Java基础?看完以后再也不惧怕面试了
查看>>
Java改环境变量把path修改了,win10系统修改JDK版本后配置环境变量不生效
查看>>
java编程cpu选i5还是i7,i5处理器和i7哪个好_i5和i7怎么选择-系统城
查看>>
php字典删除指定元素,完美解决python遍历删除字典里值为空的元素报错问题
查看>>
php strip_tags如何打开,php strip_tags函数怎么用
查看>>
name.php,rewrite_name.php
查看>>
超越虚拟化-融合之道
查看>>
[转]用wget下载整个网站
查看>>
Javascript之继承(其他方式)
查看>>
薏米红豆粥功效及做法介绍
查看>>