多线程设计模式之十一 ActiveObject模式

说说自己的理解

首先得说明一个概念 异步
何为异步?
呃, 比如说一个2个方法,第一个方法A耗时10秒, 第二个方法B耗时10秒, 如果按照正常的调用流程来说,那整个调用链需要20秒,应为是在一个线程里面进行顺序执行的,如果A和B方法之间是没有关联的,那么我们可以进行同步执行这两个方法, 这个时候我们就可以开一个线程去执行方法B, 主线程继续执行方法A,这就是异步了。

如果B方法需要有返回值呢?
所以得有得有一个同步机制Future。

那异步和ActiveObject模式有什么联系呢?, ActiveObject模式包括了异步,那区别还有什么?
呃,ActiveObject模式是很多活着对象配合的模式,这个模式除了异步,还有一个值得注意的地方就是方法和方法的执行进行了分离,这也是他和Furure的一个区别, Future也是实现了异步,但是Future模式,写代码的需要关系方法的执行逻辑,然后把这个逻辑用FutureTask包装给线程池去执行,而ActiveObject模式则是不同, 应为方法的执行是由ActiveOject里面的对象进行实现的,用户其实是不需要进行自己的方法实现,只需要按照需要提供方法入参就行,如果需要返回值,就返回一个Future对象进行同步, 那关键点来了, 调用者不关心方法的实现只用调用就行了, 那这个用户调用这个方法则需要一个代理对象把用户的入参封住为请求对象,然后放入队列里面,接着执行线程去拉取队列的请求对象,调用对应的方法逻辑。

所以这个流程设计到的对象为
用户方法: 用户方法接口
代理对象: 代理用户的方法接口,把用户的入参封住成请求对象,放入请求对象队列。
请求队列: 这里使用生产者和消费者模式,为了弥补客户端方法调用,和消费方法消费请求参数速度上的差异。
调度执行线程:这个线程去拉取请求队列里面的请求对象,然后执行对应的方法。
执行结果对象:这个对象类似Future,需要进行结果封住为同步机制,为了避免用户线程去求方法的放回结果,但是这个时候方法还没有执行结果,结果还没有,所以我们需要阻塞用户线程,当有执行结果的时候在唤醒用户线程。
用户请求对象对应的执行方法对象:这个对象方法需要接收用户的请求参数的方法入参,执行方法。给出返回结果。

大概就先这些吧。。。

示意图

ActiveObject多线程设计模式理解图

**思考:**上面这个图还有那些地方是线程安全的,那些地方不是线程安全的,那些地方可以进行优化,
emmm:

Proxy主动对象是线程安全的,他只是负责造出请求对象然后放入队列,然后给客户端返回一个Future或者void,Proxy是不需要共享变量。
请求对象: 一个方法请求封住一个请求对象,一个请求对象只能被一个excute执行,所以不存在线程安全
请求队列: 应为多个客户端线程调用代理,代理的方法把请求对象塞入队列,所以本质就是多线程塞队列,所以有线程安全问题,
Excute:线程安全

优化点: 多个队列多个Excute

实例

Do not talk,show me the code. 哈哈哈
** 为了代理用户方法接口,呃这里我选择使用动态代理实现Proxy**

客户端接口

public interface SleepService {
    String sleep();
}

Proxy

/**
 * 代理
 * @Author: puhaiguo
 * @Date: 2022-07-16 02:39
 * @Version 1.0
 */
public class Proxy implements InvocationHandler {

    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Callable callable = ()->{
            System.out.println(Thread.currentThread().getName() + " 异步线程睡觉了");
            TimeUnit.SECONDS.sleep(5);
            System.out.println(Thread.currentThread().getName() + " 异步线程睡醒了");
            return "hello world";
        };
        FutureTask futureTask = new FutureTask<>(callable);
        threadPoolExecutor.submit(futureTask);
        return futureTask.get();
    }
}

测试

public class Test {
    public static void main(String[] args) {
        SleepService sleepService = (SleepService) Proxy.newProxyInstance(com.manythread.threaddesign.eleven.train2.Proxy.class.getClassLoader(), 
                new Class[]{SleepService.class}, new com.manythread.threaddesign.eleven.train2.Proxy());
        System.out.println(Thread.currentThread().getName()+ " " + sleepService.sleep());
    }
}

结果

在这里插入图片描述

总结

ActiveObject 和 Future 模式两者都是异步的, 他们之间最大的区别在于,Future模式的方法逻辑还是需要客户端自己编码, 而ActiveObject的客户端要执行的方法是由活动对象代劳。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值