首页 > 代码库 > [Java聊天室服务器]实战之四 线程类

[Java聊天室服务器]实战之四 线程类

前言

学习任何一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的“多谋善断";本系列虽然涉及的是socket相关的知识,但学习之前,更想和广大程序员分享的是一种心境微笑:学习是一个循序渐进的过程,心态应该随时调节,保持戒骄戒躁的状态。比如最近在看网易公开课MIT《算法导论》,老师提到,学习算法之前要计算机数学+离散数学+概率论等课程的知识,所以一直学不好算法的程序员不妨从基础入手,这都是中国式教育惹的祸啊!(此处省略一万字......)


项目源码:Socket_Chat

目录

      • [Java聊天室服务器]实战之一 开篇介绍(已完成)
      • [Java聊天室服务器]实战之二 监听类(已完成)
      • [Java聊天室服务器]实战之三 接收循环(已完成)
      • [Java聊天室服务器]实战之四 线程类(已完成)
      • [Java聊天室服务器]实战之五 读写循环(服务端)(已完成)
      • [Java聊天室服务器]实战之六 去除死链接(未完成)
      • [Java聊天室服务器]实战之七 客户端类(未完成)
      • [Java聊天室服务器]实战之七 读写循环(客户端)(未完成)

正文

温故而知新

让我们再看一下7个功能点列表:


  • 监听类
  • 接收循环
  • 线程类
  • 读写循环(服务端)
  • 去除死链接
  • 客户端类
  • 读写循环(客户端)

我们已经处理完头两个,并且正在工作,我们关心服务端的核心。接下来的三步将要处理连接专门的客户端 -- 每个线程类。我们在会在这一节中编译它。

—————————————————————————————————————————————————————————————————————————

什么是线程?

 Java语言的两个主要优点:网络和多线程。也不是说其他语言就不支持上面的功能 -- 它们也支持。但是Java语言的抽象可以很简洁地提供这些功能,特别对于商业语言来说。


线程一般定义为单个进程里面独立的控制线。真实的意思是说在同一时间,多线程的程序具有多线程,在其内部具有半自主活动的特点。


多线程类似于一个任务和多任务的概念,除了在一个程序中的多个线程可以共享相同的数据空间的不同。并且这样让风向数据更加直接和有效率 -- 同样变得更加容易混乱,不受控制。

—————————————————————————————————————————————————————————————————————————

为什么使用多线程?



关于线程的细节讨论超出了本教程的范围。在你的程序中你有许多原因使用多线程,但对于构造聊天服务器,端有一条最中肯的原因是:输入/输出。


你的聊天室服务端适合客户端的用户通信的(感觉上是)。用户通常比服务端更慢,意味着你的服务器代码需要花费许多的时间来等待用户简单的输入信息。而且你也不知道哪个客户端先说。如果你有一个线程,等待用户 #0 说出了一些事,接着也就不会知道用户#1到#10在发疯的说一些事情。


正是由于这一点,我们要为每一个连接系统的用户创建线程。多线程的优点是当一个线程监听迟钝用户说出一些事情,它实际上会休眠知道有事情来到了该用户面前。与此同时,另一个线程可以从另一个用户接受信息。实际上,多线程允许尽可能快速响应每个用户的请求。


实际上本教程,关于多线程你需要知道的是为每个连接创建了线程。这条线程自己,或多或少会关心服务的连接。

—————————————————————————————————————————————————————————————————————————

线程类


在Java程序中,任何申请线程的类都会实现Runnable接口。或者你可以简单的继承 java.lang.Thread类。我们选择后一种,没有特殊的原因:


public class ServerThread extends Thread
{
// ...
}


—————————————————————————————————————————————————————————————————————————

构造函数

我们的构造函数有两个参数 -- 服务器对象和Socket对象。


Socket对象是必须的,因为线程整个的目的就是使用socket和其他的线程通信。


服务端对象回来稍后派上用场。下面的代码:

// 构造函数
public ServerThread( Server server, Socket socket ) {
// 保存参数
this.server = server;
this.socket = socket;
// 启动线程
start();
}

—————————————————————————————————————————————————————————————————————————

结束语

注意这个构造函数代码仍然会运行在主要服务器线程。最后一行代码,当调用start()方法是,重点是那个新的线程会被启动。该类会执行run()方法,这一点会在下一节中解释。

参考文献

[1]. Building  a Java chart server

[2]. Java sockets 101以及中文系列 JAVA套接字(Socket)101

[3]. Java socket通信基本原理介绍