客户端的多线程

1.多线程中的对象


对象可能被多线程访问,而这里的线程可以分为两类:
对象内部为完成业务逻辑而创建的线程,线程需要访问对象。
对象外部使用该对象的线程。
如果更细一步划分,外部线程分为拥有者线程和其它线程,拥有者负责初始化该对象。


在此基础上,可以看看对象的生命周期。
而生命周期的开始是容易确定的,但是对象生命周期在哪个线程上结束?


1.1对象可以在内部线程上析构吗?
如果内部线程是完成业务逻辑,则对象不适合在这样的线程上析构,这样带来的逻辑关系就是
对象拥有线程,线程又控制对象的生命周期。好点的做法应该是对象在生命周期终止的时候,
中止这些内部线程。如果内部线程是一个GC线程,也就是设计中专门用来析构对象的,这取
决于具体设计(比如为性能考虑,专门用一个线程来回收资源)。


1.2对象的并发性。
对象的并发性是指是否可以在多线程中调用对象的方法。允许多线程调用时有两种模式,一种
是每个线程中直接调用对象的方法,另一种是在一个线程中直接调用对象的方法在其它线程拥
有对象的代理,通过代理调用对象的方法时动作在能直接调用方法的线程内执行。


第一种模式要求对象提供的服务接口具有线程安全性,会提高对象的复杂度。一般都通过锁来
实现,如果有多个锁,就需要注意按一定顺序获取锁。如果在某个线程上获取锁后发生异常,
整个对象就杯具了。


而第二种模式只需要认为对象在单线程中工作,但是需要额外的跨线程调用的机制。该模式有
一个简单的实现,调用方法时创建一个事件,然后生成一个闭包(事件在闭包中),通过消息
把闭包传到目标线程(一般要求目标线程有消息循环或EventLoop),目标线程完成工作后,把
结果放在闭包中,然后激发事件。在调用者线程中,可以同步等待,也可以等待超时。这不就
是Future模式么?


1.3对象的析构策略。
在第一种模式中,可以在最后一个拥有引用计数的线程中析构,也可以将析构动作强行推到固定
线程中析构(只考虑固定线程为拥有者线程的情况)。


[如果再时髦一点,可以加入弱引用(弱指针),在需要使用该对象提供的服务时,提升为强指针。
仔细想想,在生命周期问题上和直接用强指针没啥大区别。直接使用强指针需要在该线程拥有这
个对象的引用时,加一个引用计数,而弱指针直到该线程需要访问对象时才提升为强指针,增加
引用计数。对对象所在的析构线程没啥影响,对象仍然可能在任意的外部线程析构。]


如果在最后一个拥有引用计数的线程中析构,析构时会释放对象拥有的资源,或许,依赖于其它
资源,这就要求拥有的其它资源的线程安全性有一定保障,需要该对象知道这些资源的线程安全
特征。依赖组合在一起会提升系统复杂度。使用其它技术也许能解决一些依赖,但是系统复杂度
还是比较大。所以,在系统复杂的情况下,倾向于使用在固定线程中析构的策略,也就要求有在
某个线程中执行析构函数的机制。


在第二种模式中,由于非拥有者线程拥有的是代理,在语义上不会影响对象的生命周期,也就是
说代理生命周期可以大于对象生命周期,只是在调用方法时发现对象已经销毁而已。因此该模式
下一般认为析构动作在拥有者线程中。


通过两种模式的比较,我们都发现需要区分拥有者线程和使用者线程。其中在模式一中,拥有者
线程的存在性主要是析构时的依赖所引入的,否则,除去拥有者创建对象以外,拥有者线程和使
用者线程没有区别。


在两种模式的比较中,隐隐约约都出现了在指定线程上调用方法的动作。




1.5考虑一下使用者如何调用对象的方法。
一般而言,使用者是业务逻辑。(对象本身也是业务逻辑的一种,只是可能处在较低的层次而已)
如果某个业务需要开线程或者使用已知线程,往往在同一时刻,逻辑只在一个线程上工作。
看一个例子,根据某本书从服务器拉取和书相关的推荐信息。拿到本地的书的信息需要调用某个对象
的方法,我们在业务发起线程中拿到书的信息,在IO线程中下载,然后到COMPUTE线程中解析结果,回
到发起线程中发出推荐消息。整个业务分为几个阶段,同一个阶段只存在于一个线程。而对书的信息
的获取,只在最开始获取一次,不是等到IO线程中再去查询本地的书的信息。我们的本地的书的信息
只能在一个线程中访问。


客户端的业务中难以遇到平等的多线程(平等的多线程的例子是完成端口的服务线程)。开多线程
的意义在于不会阻塞线程,而为了实现这点,应该把业务分为若干步,每一步放到一个线程里去做。


在业务逻辑的层次上做这样的拆分往往是可行的,除非对象提供的服务足够底层,面向的不是业务
逻辑,而是随时都可能用到该服务(比如面向语言,提供存储分配服务),除非业务逻辑对结果的
实时性有较高要求:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值