Leader Follower线程模型简单实现

来源:互联网 发布:java拆分字符串 编辑:程序博客网 时间:2024/05/29 10:33

 在我们编写网络服务程序时,比较简单的方式是per client per thread模型,这种模型当客户端连接数快速增长是就会出现性能瓶颈,我们不能不断的开启新的线程,当然我们肯定是会使用线程池,但是线程的管理和频繁的线程调度也会影响性能.

java 1.4给我们带来了NIO编程模型,由于它的读写操作都是无阻塞的,这样使我们能够只用一个线程处理所有的IO事件,当然我们不会真的只用一个线程来处理,比较常见的编写NIO网络服务程序的模型是半同步-半异步模式,其实现原理大体上是单线程同步处理网络IO请求,当有请求到达时,将该请求放入一个工作队列中,由另外的线程处理,主线程继续等待新的网络IO请求,这种编程模型的缺点主要是:
1.使用工作队列带来的内存的动态分配问题
2.每次网络IO请求,总是分配给另外一个线程处理,这样频繁的线程的context switching也会 影响性能

解决的方案是使用Leader-Follower线程模型,它的基本思想是所有的线程被分配成两种角色:
Leader和Follower,一般同时只有一个Leader线程,所有的Follower线程排队等待成为Leader线程,线程池启动时自动产生一个Leader负责等待网络IO事件,当有一个事件产生时,Leader线程首先通知一个Follower线程,并将其提拔为新的Leader,然后自己去处理这个网络事件,处理完毕后加入Follower线程等待队列,等待重新成为Leader.

 

关键点:
(1)只有1个leader线程,可以有若干的follower线程;
(2)线程有3种状态:leading/processing/following;
(3)有一把锁,抢到的就是leading;
(4)事件来到时,leading线程会对其进行处理,从而转化为processing状态;
(5)处理完成后,尝试抢锁,抢到则又变为leading,否则变为followering;
(6)followering不干事,就是抢锁,力图成为leading;


代码 http://blog.csdn.net/jmxyandy/article/details/7338896 .

follower 的排队依靠 monitor 的锁 sla 的排队.  公平锁,非公平锁.锁排队.

虽然线程池也是 leader,follower 的. 但是多了一个 queue.


###

半同步半异步模式以及Leader_Follwer模式

1.半同步/半异步(half-sync/half-async):

在网上一份资料中引用了一本貌似很经典的书里的比喻:

许多餐厅使用 半同步/半异步 模式的变体。例如,餐厅常常雇佣一个领班负责迎接顾客,并在餐厅繁忙时留意给顾客安排桌位,
为等待就餐的顾客按序排队是必要的。领班由所有顾客“共享”,不能被任何特定顾客占用太多时间。当顾客在一张桌子入坐后,
有一个侍应生专门为这张桌子服务。

按照另一份似乎比较权威的文档的描述,要实现半同步/半异步模式,需要实现三层:异步层、同步层、队列层。因为很多操作
采用异步方式会比较有效率(例如高效率的网络模型似乎都采用异步IO),但是异步操作的复杂度比较高,不利于编程。而同步
操作相对之下编程要简单点。为了结合两者的优点,就提出了这个模式。而为了让异步层和同步层互相通信(模块间的通信),系
统需要加入一个通信队列。异步层将操作结果放入队列,同步层从队列里获取操作结果。

回过头来看看我之前写的那个select网络模型代码,个人认为基本上算是一个半同步半异步模式的简单例子:Buffer相当于通信
队列,网络底层将数据写入Buffer,上层再同步地从该队列里获取出数据。这样看来似乎也没什么难度。 = =


2.领导者/追随者(Leader/Followers):

同样,给出别人引用的比喻:

在日常生活中,领导者/追随者模式用于管理许多飞机场出租车候车台。在该用例中,出租车扮演“线程”角色,排在第一辆的出
租车成为领导者,剩下的出租车成为追随者。同样,到达出租车候车台的乘客构成了必须被多路分解给出租车的事件,一般以先进
先出排序。一般来说,如果任何出租车可以为任何顾客服务,该场景就主要相当于非绑定句柄/线程关联。然而,如果仅仅是某些
出租车可以为某些乘客服务,该场景就相当于绑定句柄/线程关联。

其实这个更简单,我记得<unix网络编程>中似乎提到过这个。总之有一种网络模型(connection-per-thread?)里,一个线程用于
accept连接。当接收到一个新的连接时,这个线程就转为connection thread,而这个线程后面的线程则上升为accept线程。这里,
accept线程就相当于领导者线程,而其他线程则属于追随者线程。


原创粉丝点击