目 录CONTENT

文章目录

设计模式案例

半糖
2025-04-27 / 0 评论 / 0 点赞 / 3 阅读 / 21069 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2025-04-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

本文作为一个记录,记录在开发过程中使用到的设计模式,以后做规整。

多种设计模式相结合的案例

并发工具

用到的设计模式

ThreadMDCUtil:装饰器模式(Decorator Pattern)

Beans:策略模式(Strategy Pattern)

InvokerUtil:命令模式(Command Pattern)

直接上代码

import cn.hutool.core.bean.BeanUtil;
import com.rc.framework.common.util.thread.InvokerUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;



public class Beans implements Serializable {


    /**
     *
     * @param toList
     * @param fromList
     * @param eqFun
     * @param <T>
     */
    public static<T,R> void addAllToListNotExist(List<T> toList,List<T> fromList,Function<T,R> eqFun){
        if (CollectionUtils.isEmpty(fromList)){
            return;
        }
        fromList.forEach(data-> addToListNotExist(toList,data,eqFun));
    }

    /**
     *
     * @param list
     * @param t
     * @param eqFun
     * @param <T>
     */
    public static<T,R> void addToListNotExist(List<T> list,T t,Function<T,R> eqFun){
        if (list.stream().anyMatch(data->{
            Object o1 = eqFun.apply(data);
            Object o2 = eqFun.apply(t);
            if (o1==o2){
                return true;
            }
            if (o1 == null){
                return false;
            }
            return o1.equals(o2);
        })){
            return;
        }
        list.add(t);
    }


    /**
     * copy 并创建一个新的对象
     *
     * @param b
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T> T newObj(Object b, Class<T> targetClass) {
        if (b == null) {
            return null;
        }
        T instantiate = BeanUtils.instantiateClass(targetClass);
        BeanUtil.copyProperties(b, instantiate);
        return instantiate;
    }

    /**
     * forEach并行执行
     *
     * @param action
     * @param <T>
     * @return
     */
    public static <T> void forEachConcurrent(Collection<T> coll,int invokerNum, Consumer<? super T> action)  {
        if (action == null || coll==null || coll.isEmpty()) {
            return;
        }
        if (invokerNum > coll.size()) {
            invokerNum = coll.size();
        }
        ConcurrentLinkedQueue<T> queue = new ConcurrentLinkedQueue<>(coll);
        InvokerUtil.Invoker[] invokers = new InvokerUtil.Invoker[invokerNum];
        for(int i=0;i<invokerNum;i++){
            invokers[i] = ()->{
                T data;
                while(null != (data = queue.poll())) {
                  action.accept(data);
              }
            };
        }
        InvokerUtil.invoiceMulti(invokers);
    }

    /**
     * forEach并行执行
     *
     * @param action
     * @param <T>
     * @return
     */
    public static <K,T> void forEachConcurrent(Map<? super K, ? super T> map,int invokerNum,BiConsumer<? super K, ? super T> action)  {
        if (action == null || map==null || map.isEmpty()) {
            return;
        }
        if (invokerNum > map.size()) {
            invokerNum = map.size();
        }
        ConcurrentLinkedQueue<Map.Entry<? super K, ? super T>> queue = new ConcurrentLinkedQueue<>(map.entrySet());
        InvokerUtil.Invoker[] invokers = new InvokerUtil.Invoker[invokerNum];
        for(int i=0;i<invokerNum;i++){
            invokers[i] = ()->{
                Map.Entry<? super K, ? super T> data;
                while(null != (data = queue.poll())) {
                    action.accept((K)data.getKey(),(T)data.getValue());
                }
            };
        }
        InvokerUtil.invoiceMulti(invokers);
    }



    /**
     * copy 并创建一个新集合
     *
     * @param b
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T,R> List<R> newObj(List<T> b, final Class<R> targetClass) {
        return newObj(b, q-> newObj(q, targetClass));
    }


    /**
     * copy 并创建一个新集合
     *
     * @param list
     * @param converter
     * @param <T>
     * @return
     */
    public static <T,R> List<R> newObj(List<T> list,Function<T,R> converter) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        ArrayList<R> temp = new ArrayList<>();
        for (T ob : list) {
            temp.add(converter.apply(ob));
        }
        return temp;
    }



    /**
     * @param b
     * @param <T>
     * @return
     */
    public static <T> T choseOne(List<T> b) {
        if (CollectionUtils.isEmpty(b)) {
            return null;
        }
        return b.get(0);
    }

    /**
     * @param b
     * @param <T>
     * @return
     */
    public static <T> T choseOne(T ...b) {
        if (b==null || b.length<1) {
            return null;
        }
        return b[0];
    }

    /**
     * 判断字段属性值是否在集合中
     *
     * @param list
     * @param func
     * @param propVal
     * @param <T>
     * @param <R>
     * @return
     */
    public static <T, R> boolean propIsExistObjList(List<? extends T> list, Function<T, R> func, R propVal) {
        if (propVal == null || CollectionUtils.isEmpty(list)) {
            return false;
        }
        return list.stream().anyMatch(d -> propVal.equals(func.apply(d)));
    }


    /**
     * 获取对象中的属性
     *
     * @param o
     * @param func
     * @param defaultVal
     * @param <T>
     * @param <R>
     * @return
     */
    public static <T, R> R getAttrValue(T o, Function<T, R> func, R defaultVal) {
       if (o==null){
           return defaultVal;
       }
       R result = func.apply(o);
       return result==null?defaultVal:result;
    }



    /**
     * 获取属性值
     *
     * @param list
     * @param getFun
     * @param <T>
     * @param <R>
     * @return
     */
    public static<T,R>  List<R> getPropertyList(List<? extends T> list, Function<T, R> getFun) {
        if (CollectionUtils.isEmpty(list)){
            return null;
        }
        List<R> result = new ArrayList<>();
        list.forEach(d -> result.add(getFun.apply(d)));
        return result;
    }

    /**
     * 获取属性值
     *
     * @param list
     * @param eqFun
     * @param propVal
     * @param getFun
     * @param <T>
     * @param <R>
     * @return
     */
    public static<T, Q,R>  R getPropInObjListEqProp(List<? extends T> list, Function<T, Q> eqFun, Q propVal, Function<T, R> getFun) {
        T t = getObjListEqProp(list, eqFun, propVal);
        if (t == null){
            return null;
        }
        return getFun.apply(t);
    }


    /**
     * 获取属性值
     *
     * @param list
     * @param eqFun
     * @param propVal
     * @param <T>
     * @return
     */
    public static<T,Q>  T getObjListEqProp(List<? extends T> list, Function<T, Q> eqFun, Q propVal) {
        if (propVal == null || CollectionUtils.isEmpty(list)) {
            return null;
        }
        T t = list.stream().filter(d -> propVal.equals(eqFun.apply(d))).findFirst().orElse(null);
        return t;
    }



    /**
     * copy对象属性 当目标对象属性为空时
     */
    public static <T, R> void copyPropIfTargetEmpty(T source, T target, Map<Function<T, R>, BiConsumer<T, R>> funMap) {
        if (funMap == null || funMap.size() < 1) {
            return;
        }
        funMap.forEach((get, set) -> {
            R targetPropVal = get.apply(target);
            if (targetPropVal == null || StringUtils.isBlank(targetPropVal.toString())) {
                set.accept(target, get.apply(source));
            }
        });
    }

    /**
     *
     * @param o
     * @param r
     * @param <T>
     * @return
     */
    public static<T> T isNull(T o,T r){
        if (o==null){
            return r;
        }
        return o;
    }

    /**
     *
     * @param o
     * @param r
     * @param <T>
     * @return
     */
    public static<T> T isEmpty(T o,T r){
        if (o==null){
            return r;
        }
        if(StringUtils.isBlank(o.toString())){
            return r;
        }
        return o;
    }


    /**
     *
     * @param o
     * @param replaceFun
     * @param <T>
     * @return
     */
    public static<T,R> R isNull(T o,Function<T,R> replaceFun){
        if (o==null){
            return null;
        }
        return replaceFun.apply(o);
    }


    /**
     *
     * @param o
     * @return
     * @param <T>
     * @param <Q>
     */
    public static<T,Q extends Collection<T>> void ifNotEmpty(Q o,Consumer<Q> replaceFun){
        if (o==null){
            return;
        }
        if(CollectionUtils.isEmpty(o)){
            return;
        }
        replaceFun.accept(o);
    }

    /**
     *
     * @param o
     * @return
     * @param <T>
     * @param <Q>
     */
    public static<T,Q extends Collection<T>> void forNotEmpty(Q o,Consumer<T> replaceFun){
        if (o==null){
            return;
        }
        if(CollectionUtils.isEmpty(o)){
            return;
        }
        for (T t:o){
            replaceFun.accept(t);
        }
    }

    /**
     *
     * @param o
     * @param r
     * @return
     * @param <T>
     * @param <Q>
     */
    public static<T,Q extends Collection<T>> Q isEmpty(Q o,Q r){
        if (o==null){
            return r;
        }
        if(CollectionUtils.isEmpty(o)){
            return r;
        }
        return o;
    }



    /**
     *
     * @param list
     * @param objs
     * @return
     */
    public static boolean collectionContainsAny(List list,Object ...objs){
        if (CollectionUtils.isEmpty(list) || objs==null){
            return false;
        }
        List<Object> contains = Arrays.asList(objs);
        for (Object o:list){
            if (contains.contains(o)){
                return true;
            }
        }
        return false;
    }


    /**
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean eq(Object a,Object b){
        if (a==b){
            return true;
        }
        return a!=null && a.equals(b);
    }

    /**
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean eqAny(Object a,Object ...b){
        if (b==null){
            return false;
        }
        for (Object i:b){
            if (eq(a,i)){
                return true;
            }
        }
        return false;
    }

    /**
     *
     * @param list
     * @param keyFun
     * @return
     * @param <K>
     * @param <V>
     */
    public static <K,V> Map<K,V> toMap(Collection<V> list,Function<V,K> keyFun){
        if (CollectionUtils.isEmpty(list)){
            return new HashMap<>();
        }
        Map<K,V>  result = new LinkedHashMap<>(list.size());
        list.forEach(data-> result.put(keyFun.apply(data),data));
        return result;
    }
}
import com.rc.framework.common.util.log.ThreadMDCUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
public abstract class InvokerUtil {


    //核心线程数,超过则放入等待队列,若等待队列已满(表示没有空闲线程来执行当前提交的任务)则创建新的线程,若线程数超过最大线程限制则抛出Reject异常
    //最大线程
    //非核心线程最大空闲存活时间为60s
    //核心现场池,总要业务
    private static final ExecutorService CORE_THREAD_POOL = new ThreadPoolExecutor(
            20,
            200,
            60,
            TimeUnit.SECONDS,
            new SynchronousQueue<>());
    //非核心现场池,相对总要业务
    private static final ExecutorService SYNC_THREAD_POOL = new ThreadPoolExecutor(
            20,
            200,
            60,
            TimeUnit.SECONDS,
            new SynchronousQueue<>());
    //次要现场池
    private static final ExecutorService SECONDARY_THREAD_POOL = new ThreadPoolExecutor(
            20,
            200,
            60,
            TimeUnit.SECONDS,
            new SynchronousQueue<>());


    /**
     * 异步执行优先 线程池满了转同步
     *
     * @param invokers
     * @throws Throwable
     */
    public static void invoiceAsyncMulti(Invoker... invokers) {
        if (invokers == null || invokers.length < 1) {
            return;
        }
        for (Invoker invoker : invokers) {
            if (invoker == null) {
                continue;
            }
            try {
                SYNC_THREAD_POOL.submit(ThreadMDCUtil.wrap(new InvokerCallable(invoker), MDC.getCopyOfContextMap()));
            } catch (RejectedExecutionException e) {
                log.warn("Invoker-异步线程池耗尽 转同步");
                invoker.invoke();
            }
        }

    }

    /**
     * @param invokers
     * @throws Throwable
     */
    public static void invoiceMulti(List<Invoker> invokers) {
        if (invokers == null || invokers.size() < 1) {
            return;
        }
        invoiceMulti(invokers.toArray(new Invoker[]{}));
    }

    /**
     * @param invokers
     * @throws Throwable
     */
    public static void invoiceMulti(Invoker... invokers) {
        if (invokers == null || invokers.length < 1) {
            return;
        }
        //只有单个任务时,就不创建异步线程了
        if (invokers.length == 1) {
            invokers[0].invoke();
            return;
        }
        List<Future<Object>> futures = new ArrayList<>();
        for (Invoker invoker : invokers) {
            try {
                if (invoker == null) {
                    continue;
                }
                futures.add(CORE_THREAD_POOL.submit(ThreadMDCUtil.wrap(new InvokerCallable(invoker), MDC.getCopyOfContextMap())));
            } catch (RejectedExecutionException e) {
                invoker.invoke();
            }
        }
        for (Future<Object> ft : futures) {
            try {
                ft.get();
            } catch (Exception e) {
                log.error("invokeMulti fail", e);
                throw new RuntimeException(e);
            }
        }
    }


    /**
     * @param second
     * @param invokers
     * @throws Throwable
     */
    public static void invoiceMulti(int second, Invoker... invokers) throws TimeoutException {
        if (invokers == null || invokers.length < 1) {
            return;
        }
        List<Future<Object>> futures = new ArrayList<>();
        for (Invoker invoker : invokers) {
            futures.add(SYNC_THREAD_POOL.submit(ThreadMDCUtil.wrap(new InvokerCallable(invoker), MDC.getCopyOfContextMap())));

        }
        for (Future<Object> future : futures) {
            try {
                future.get(second, TimeUnit.SECONDS);
            } catch (TimeoutException e) {
                throw e;
            } catch (Exception e) {
                log.error("invokeMulti fail", e);
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * @param millis
     * @param invokers
     * @throws Throwable
     */
    public static void invoiceMultiMillis(int millis, Invoker... invokers) throws TimeoutException {
        if (invokers == null || invokers.length < 1) {
            return;
        }
        List<Future<Object>> futures = new ArrayList<>();
        for (Invoker invoker : invokers) {
            futures.add(SYNC_THREAD_POOL.submit(ThreadMDCUtil.wrap(new InvokerCallable(invoker), MDC.getCopyOfContextMap())));

        }
        for (Future<Object> future : futures) {
            try {
                future.get(millis, TimeUnit.MILLISECONDS);
            } catch (TimeoutException e) {
                throw e;
            } catch (Exception e) {
                log.error("invokeMulti fail", e);
                throw new RuntimeException(e);
            }
        }
    }


    /**
     * @param second
     * @param invokers
     * @throws Throwable
     */
    public static void invoiceMultiNoMatter(int second, Invoker... invokers) {
        try {
            invoiceMulti(second, invokers);
        } catch (Exception e) {
            log.error("invokeMulti fail", e);
        }
    }


    /**
     * @param millis
     * @param invokers
     * @throws Throwable
     */
    public static boolean invoiceMultiNoMatterMillis(int millis, Invoker... invokers) {
        try {
            invoiceMultiMillis(millis, invokers);
            return true;
        } catch (Exception e) {
            log.error("invokeMulti fail", e);
            return false;
        }
    }


    /**
     * @param invoker
     * @throws Throwable
     */
    public static void invoiceMultiAsyn(Invoker invoker) {
        if (invoker == null) {
            return;
        }
        SYNC_THREAD_POOL.submit(ThreadMDCUtil.wrap(new InvokerCallable(invoker), MDC.getCopyOfContextMap()));
    }

    /**
     * @param invoker
     * @throws Throwable
     */
    public static void invoiceMultiAsynNoMatter(Invoker invoker) {
        if (invoker == null) {
            return;
        }
        try {
            SECONDARY_THREAD_POOL.submit(ThreadMDCUtil.wrap(new InvokerCallable(invoker), MDC.getCopyOfContextMap()));
        } catch (Exception e) {
            log.warn("Invoker-异步线程池耗尽,丢弃", e);
        }
    }

    /**
     * @param time
     */
    public static void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            log.warn("Thread.sleep err", e);
        }
    }

    public interface Invoker {
        void invoke();
    }

    private static class InvokerCallable implements Callable<Object> {
        protected Invoker invoker;

        InvokerCallable(Invoker invoker) {
            this.invoker = invoker;
        }

        @Override
        public Object call() throws Exception {
            invoker.invoke();
            return true;
        }
    }
}
import org.slf4j.MDC;

import java.util.Map;
import java.util.concurrent.Callable;

public class ThreadMDCUtil {
    public static void setTraceIdIfAbsent() {
        if (MDC.get(LogMDCUtil.LOG_ID) == null) {
            MDC.put(LogMDCUtil.LOG_ID, LogMDCUtil.getLogId());
        }
    }

    public static <T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
        return () -> {
            if (context == null) {
                MDC.clear();
            } else {
                MDC.setContextMap(context);
            }
            setTraceIdIfAbsent();
            try {
                return callable.call();
            } finally {
                MDC.clear();
            }
        };
    }

    public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
        return () -> {
            if (context == null) {
                MDC.clear();
            } else {
                MDC.setContextMap(context);
            }
            setTraceIdIfAbsent();
            try {
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区