在我们编写网络服务程序时,比较简单的方式是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.
这个线程模型主要解决了内存的动态分配问题,我们不需要不断的将到来的网络IO事件放入队列,并且等待网络IO事件的线程在等到网络事件的发生后,是自己处理的这个事件,也就是说没有context switching的过程.
下面是简单的代码演示
首先定义我们的事件模型Event
public interface Event {
SelectableChannel getChannel();
}
它的实现:
public class DefaultEventImpl implements Event {
private SelectableChannel channel;
public DefaultEventImpl(SelectableChannel channel) {
this.channel = channel;
}
@Override
public SelectableChannel getChannel() {
return this.channel;
}
}
然后定义我们的EventHandler
public interface EventHandler {
/**
* this can be blocked
*
* @return Event
*/
Event pollEvent();
void handleEvent(Event e);
}
其中的pollEvent()方法会阻塞,当有网络请求时返回一个我们封装的Event对象,其实里面大体上就是select()方法
接下来是我们的核心部分,Leader-Follower线程池的定义
public interface LFThreadPool {
void start();
void promoteLeader();
void waitToBeLeader();
}
通过start方法启动线程池,然后调用一次promoteLeader产生了一个Leader线程等待网络事件的到达,其余线程则是waitToBeLeader的状态.
我们还定义了一个Worker线程模型
public interface WorkerThread extends Runnable {
void start();
}
start方法主要是启动所有的workers,其实觉得可以省去这个接口的
然后看一下我们的worker thread实现
public class DefaultWorkerThread implements WorkerThread {
private LFThreadPool pool;
private EventHandler handler;
private boolean isActive;
public DefaultWorkerThread(DefaultLFThreadPoolImpl pool,
EventHandler handler) {
this.pool = pool;
this.handler = handler;
}
@Override
public void run() {
while (isActive) {
this.pool.waitToBeLeader();
//阻塞等待pollEvent返回待处理的事件,此处等待的是Leader线程
Event event = handler.pollEvent();
//notify 唤醒一个正在等待的线程成为leader,由它来等待新的
//网络事件到达,自己则去处理当前的IO事件
this.pool.promoteLeader();
handler.handleEvent(event);
//处理完毕后you重新waitToBeLeader等待成为Leader
}
}
@Override
public synchronized void start() {
if (!isActive) {
isActive = true;
}
new Thread(this).start();
}
}
最后是我们的线程池的实现部分,看一下LFThreadPool的实现
public class DefaultLFThreadPoolImpl implements LFThreadPool {
private WorkerThread[] workers;
private boolean isActive;
private Object semaphore = new Object();
public DefaultLFThreadPoolImpl(int poolSize, EventHandler handler) {
workers = new DefaultWorkerThread[poolSize];
for (int i = 0; i < poolSize; i++) {
workers[i] = new DefaultWorkerThread(this, handler);
}
}
@Override
public synchronized void start() {
if (!isActive) {
//启动所有的workers
for (int i = 0; i < workers.length; i++) {
workers[i].start();
}
//保证所有的workers已经启动
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//产生一个Leader线程
promoteLeader();
isActive = true;
}
}
@Override
public void promoteLeader() {
synchronized (semaphore) {
semaphore.notify();
}
}
@Override
public void waitToBeLeader() {
synchronized (semaphore) {
try {
semaphore.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
整个过程中没有动态内存分配,也没有频繁的context switching,应该可以提高部分效率,后续会发出完整的程序,欢迎大家指正.
分享到:
相关推荐
This is simulation of leader follower control system.
Leader-follower 算法的matlab算法实现
用MATLAB编写的leader_follower算法实现聚类的函数.希望能对大家有帮助....zip
在follower跟随阶段中,通过采用morphing技术,产生在复杂障碍约束下平滑的中间约束队形序列,并结合提出的队形弹簧模型,局部修正并控制follower每一时刻的速度。为解决面对动态障碍的避碰问题,基于相对速度障碍法...
领航跟随编队控制设计编队避障的一些信息,包含避障
下行异构网络中基于多领导者多跟随者博弈的功率控制算法,韩乔妮,杨博,异构网络(Heterogeneous networks, HetNets)是正在扩张的3G网络和新兴的4G网络的重要组成部分。然而,为了达到所有用户的服务质量(Quality ...
在Leader-follower框架下的多机器鱼系统队形控制中,针对Leader和Follower相对独立及落后机器鱼离队等问题,在传统的Leader-follower队形控制算法中引入模糊反馈控制器进行反馈调节,使得领航机器鱼Leader能定时检查...
Consensus control of nonlinear leader-follower multi-agent systems with actuating disturbances
多智能体系统一阶有领导者实现一致性的matlab仿真代码
Leader-Follower Output Synchronization of Linear Heterogeneous Systems With Active Leader Using Reinforcement Learning
基于Leader-follower的处置突发事件队形变换方法研究,熊景,巩青歌,针对武警部队处置突发事件时的队形变换问题,提出了一种基于跟随领航者(Leader–follower)法的队形变换方法,该方法引入几何划分,对��
网络游戏-基于Ad-Hoc网络和leader-follower算法的多机器人编队方法.zip
Implementation of Leader-Follower Formation Control of a Team of Nonholonomic Mobile Robots
Leader–Follower Consensus of Multivehicle Wirelessly Networked Uncertain Systems Subject to Nonlinear Dynamics and Actuator Fault
要启动的第一个节点将是leader,leader没有分配分区,因此请尝试在集成后启动2个实例 如何整合 const ring = require ( 'ring-election' ) let follower = ring . follower const { BECOME_LEADER , PARTITIONS_...
turtlebot follower void imageCb const sensor msgs::ImageConstPtr& msg { cv bridge::CvImagePtr cv ptr; try { cv ptr cv bridge::toCvCopy msg sensor msgs::image encodings::BGR8 ; } catch cv ...
#资源达人分享计划#
然后, 将leader-follower算法思想应用其中, 简化了算法模型; 其次, 为了满足底层仿真的需要, 对兵力实体的避障行为进行了研究, 引入了切线避障法。增加follower与leader之间的距离对leader速度的反馈, 在follower...