分享
 
 
 

使用JAVA建立稳定的多线程服务器

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

Java语言是完全面向对象的,它的线程机制和对象序列化非凡轻易使用,使用Java来建立一套多线程服务器要比使用其它语言方便的多,假如你再把它的异常处理机制利用好,那么你就可以建立一个商业级的多线程服务器了。由于采用了消息队列和Socket传输方式,所以不会出现丢消息的问题。这套服务器可以作为实时聊天服务器、多人协同的协作服务器等等。

消息系统的建立

这套服务器的消息系统采用的是对象传输的机制,而不是以前经常使用的字符串传输。采用对象传输的好处是扩展方便,如需要建立一个新的消息只需要从一个统一的基类继续下来,然后再写自己实现的方法就行了。这样也符合面向对象领域里一条重要的原则:OCP(open_closed Principle),即一个好的设计应该能够容纳新的功能的增加,但是增加的方式不是修改原有的类,而是添加新的类。

首先建立一个基类:Msg,该抽象类中有两个域sender和receiver分别纪录消息的发送者和接收者。这两个域是在构造消息类时就填写的,receiver域可以为空,空表示发给谁都可以,由转发服务器来决定。该类的方法包括取得这两个域的值和消息的处理函数。消息的处理函数process()是空函数,供继续者重载。

建立了这个抽象基类后,你就可以继续它完成你自己的类。举个例子,假如我要建立一个分组协同工作的绘图系统,而且支持组员之间的对话,那么我可以建立如下的类集合:

SendTextMsg(String sender,String receiver,String info)//向指定的人发送对话。

AddLineMsg(String sender,Point a,Point b)//在指定的点之间绘制一条直线

AddRectangle(String sender,point start,Point end)//建立指定的矩形

AddRotundaMsg(String sender,Point center,int radius)//建立指定的圆

RemoveObjectMsg(String sender,int ID)//删除指定编号的图形对象

……

以此类推,可以建立很多的消息类。在每个类的内部都由一个处理该类的方法process(),填写该方法就可以实现对消息类的处理,而服务器只负责完成消息的转发功能。这样,一套消息系统就建立了。

服务器的结构

假如要服务器实现同时为每个客户端服务,就要使用多线程,建立一个线程池,当有客户端连接时就在池中开辟一个线程为它服务。同样,要避免大量消息到达时处理不过来而导致丢失的情况,就要使用消息队列。这个服务器是分层的处理的。

服务器的工作过程是这样的,建立了一个Server类作为主类,它含有程序的入口函数main()。在构造函数中初始化一个数组存放ClientSingle类,它其实就是单独处理一个连接用户的类。然后启动一个线程PORTListenThread,该线程的作用就是监听端口上有没有人登陆,当有人连接时交给Server的addClient()处理。Server的addClient()方法会在刚才那个数组中建立一个ClientSingle对象,然后把剩下的事都交给它做。

端口监听线程类PORTListenThread

该线程类在run()函数的开始部分首先要检查serverScoket是否为空,保证循环开始时不要出错。然后进入一个死循环的监听:

while(true) { //死循环监

try{Socket clientSocket=null;

clientSocket=serverSocket.accept();

server.addClient(clientSocket);//转交Server处理

}

catch (IOException e){System.out.println("监听端口时出错"+e);}//显示错误

}

单个客户端在连接池中的映像类ClientSingle

每一个客户端连接到服务器后,服务器会自动在连接池中建立该客户端的一个映像,所有的操作都交给这个映像去具体执行,所以ClientSingle中一定要包含客户端的一些基本的信息。比如客户端的名称、登陆时间等等。在该类中有两个消息队列sendQueue(发送队列)和receiveQueue(接收队列)缓存消息。

ClientSingle类是继续自Thread的,它还是一个调用者。在初始化的时候启动两个子线程类SingleSender和SingleListener运行。SingleSender负责监听指令发送队列中有没有指令,有则发送;SingleListener负责监听有没有消息到达,有则把这些消息加入到接收队列中去,由ClientSingle处理。所以ClientSingle的主要任务就是对这两个队列的处理。这两个队列可以用Vector实现,非常地简单。

//-------将消息加入发送队列中------------

synchronized void send(Object o)

{ sendQueue.add(o);

}

为了稳定控制子线程的运行,并不鼓励在run()方法的死循环标志都用true,而是使用了一个布尔型的变量finish。外部可以通过把这个标志置为假而停止线程的运行。

发送子线程类启动后执行run()中的循环(以finish为结束标志),在该循环内首先判定ClientSingle中的发送队列是否为空,为空时睡眠一定的时间再重新判定,这也是一个while循环。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有