Java的多线程机制在Socket编程中的应用

时间:2022-10-30 02:51:16

Java的多线程机制在Socket编程中的应用

摘要:本文对Java多线程的原理与用法进行了讨论,重点讨论了将多线程机制应用到Socket编程中,从而使服务器能够同时响应来自多个客户的请求。

关键词:java;多线程;socket编程

中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)15-30796-01

The Java Multi-threading Mechanism Weaves the Application in the Distance in the Socket

XU Xiao-long

(Dept.of Computer Science,Qufu Normal University,Rizhao 276826,China)

Abstract:This paper discusses the theory and usage of Java multithreading, especially how to use multithreading in socket programming, so that the server can response the requests of many clients at the same time.

Key words:java; multithreading; socket programming

随着分布式系统的兴起,并发多任务技术越来越重要。在现有的基于多线程的操作系统上开发并发多任务程序已成为程序设计的热点。Java是开发网络应用程序的热门技术之一,本文首先分析了Java多线程机制的特性,然后以Windows XP为平台,以JDK6.0为开发环境分析了Java的多线程机制在Socket编程中的应用。

1 线程的特点

以往所开发的程序多数是单线程的,即一个程序只有一条从头至尾的执行路线。然而现实世界的很多过程却需要多条途径同时运行,例如服务器需要同时处理多个客户的请求,多媒体程序需要对多种媒体并发控制等。

线程是指进程中单一顺序的控制流,又称为轻量级进程。每个进程可以启动几个线程,线程是最小的运行单位。操作系统的多任务特性使得线程之间独立运行,但是它们彼此共享存储空间,可能会同时操作同一内存地址。

2 Java对多线程的支持

2.1概述

Java是通过多线程机制来支持多任务和并行处理的,多线程编程是Java语言最重要的特征之一。多线程是指同时存在几个执行体,按几条不同的执行路线共同工作的情况。Java的多线程机制使得编程人员可以很方便地开发出具有多线程功能,能同时处理多个任务的功能强大的应用程序。

Java对多线程的支持表现为两个方面:一是它本身就是一个多线程体系。Java是基于多线程来执行任务的。例如,有若干个系统线程用于必要的“垃圾”回收,自动作存储器管理工作及其它系统维护工作。另外,Java内置了多线程控制机制,从而大大简化了多线程应用程序的开发。Thread类封装了所有有关线程的控制,负责线程的启动、运行、休眠、挂起、恢复、退出和终止等一般性的逻辑控制操作,并可检查线程的状态。除此之外,Thread类也实现了对线程行为的优先级的控制。由于CPU一次只能执行一个线程中的指令,因此对多线程体系而言,必须通过优先级决定线程之间的切换。

2.2线程的创建

Java是面向对象的程序语言,用Java进行程序设计就是设计和使用类,Java提供了Thread类来创建线程,线程就是Thread类或其子类的对象。

Thread thread1=new Thread();

thread1.start();

这样就创建了一个线程,并启动了该线程。启动线程就是启动线程的run()方法,而Thread类中的run()方法没有任何操作语句,所以要使线程实现预定功能,必须定义自己的run()方法。Java中通常有两种方式定义run()方法:

一是通过定义Thread类的子类,在该子类中重写run()方法。Thread子类的实例就是一个线程,启动线程就启动了子类中重写的run()方法。

二是通过实现Runnable接口,在该接口中定义run()方法。

线程被创建后处于待命状态,启动线程就是启动线程的run()方法,这是通过调用线程的start()方法来实现的。

2.3线程的优先级

对于多线程程序,每个线程的重要程度不尽相同,如多个线程在等待处理机时,往往需要优先级高的线程优先抢占到CPU得以执行;又如多个线程交替执行时,希望优先级高的线程得到CPU的时间长一些;这样,高优先级的线程处理的任务效率就高一些。

Java中线程的优先级从低到高以整数1~10表示,共分为10级,设置优先级是通过调用线程对象的setPriority()方法。

2.4线程的同步

线程的异步执行是指线程抢占CPU,不关心其它线程的状态或行为。但是在访问一些共享资源时,这种无序访问会导致无法得到正确的结果。因此当两个或多个线程需要访问同一资源时,它们需要以某种顺序来确保该资源在某一时刻只能被一个线程使用,这种方式称为同步。

Java在同步机制中提供了语言级的支持,可以通过对关键代码段使用synchronized关键字修饰来实现针对该代码段的同步操作。

2.5线程间的相互联系

可以利用wait()、notify()及notifyAll()方法发送消息实现线程间的相互联系,在同一时刻只能有一个线程访对象中的同步方法,其它线程被阻塞。通常可以用notify()或notifyAll()方法唤醒其它一个或所有线程。而使用wait()方法来使该线程处于阻塞状态,等待其它的线程用notify()唤醒。

3 多线程在Socket编程中的应用

3.1服务器端的多线程

网上数据交互的主要特点是发生的随机性,即消息的到达不存在任何预示或规律,协作双方无法预知信息到达的时间,所以要防止信息丢失。因此,需要在服务器程序中设置一个循环语句,反复检测输入流中有没有来自客户的数据。以一个简单的例子说

(上接第796页)

明这个问题:客户通过输出流将一个字符串传给服务器,服务器收到后将字符串的所有字母转换为大写,然后通过输出流回送给客户。程序如下:

public static void main(String[] args) throws Exception{

ServerSocket ss = new ServerSocket(PORT);

Socket skt = ss.accept();

DataInputStream dis = new DataInputStream(skt.getInputSream());

DataOutputStream dos = new DataOutputStream(skt.getOutputStream());

while (true) {

String s = dis.readUTF();

if (s!=null)dos.writeUTF(s.toUpperCase()); } }

该程序的一个明显缺陷是只能接收来自一个客户的数据,因为程序会停留在while语句处反复检测,这是服务器程序所不能容忍的。为了能接收来自多个客户的数据,必须采用多线程的方法。

每与一个客户建立连接后,就启动一个线程,让该线程检测输入流中有无数据,便可实现服务器同时响应多个客户的请求。方法如下:

class ServerThread extends Thread{

Socket skt = null;

DataInputStream dis = null;

DataOutputStream dos = null;

ServerThread(Socket skt1){

skt = skt1;

try{

dis = new DataInputStream(skt.getInputStream());

dos = new DataOutputStream(skt.getOutputStream());

}catch(Exception e){} }

public void run(){

while (true){

String s = dis.readUTF();

if (s!=null)dos.writeUTF(s.toUpperCase()); }}}

这样主方法就可以只负责接收客户请求,将每个请求的Socket对象作为参数传递给ServerThread的构造方法,然后将该ServerThread对象启动,便会有一个线程专门负责监听该客户的请求。主方法为:

public static void main(String[] args) throws Exception{

ServerSocket ss = new ServerSocket(PORT);

while (true){

Socket skt = ss.accept();

if (skt!=null)new ServerThread(skt).start();}}

3.2客户端的多线程

客户如果要监听服务器回送的信息,为了防止信息的遗漏,同样需要使用循环语句反复监测输入流:

while (true){

String s =-dis.readUTF();

if (s!=null) System.out.println(s);}

在这种情况下,主程序便会反复执行循环体,无法进行其它工作。如果让一个线程专门负责监听,那么该线程启动后,主程序便可解放出来处理其它事情。线程的写法可以象服务器端一样,写一个Thread的子类,也可以实现Runnable接口。

将多线程应用到Socket程序中后,便实现了客户与服务器的合理通信,既不至于遗漏信息,也不会因为监听而影响程序的其它功能。

4 结束语

本文讨论了Java的多线程机制及其使用,研究了将多线程应用于Socket程序设计的基本模型,在此模型的基础上可以方便的演化出更为复杂的程序,如聊天、远程计算等。本文对多线程及Socket编程的初学者有一定参考价值,也是研究多线程协作、即时响应等问题的基础。

参考文献:

[1]胡雯,赵海廷.JAVA多线程同步问题研究[J].软件导刊,2007,1.

[2]姜景根,李祥.基于Java的多线程并发服务器的设计与应用[J].电脑与信息技术,2007;15(1).

[3]Bruce Eckel.Think in Java[M].北京:机械工业出版社,2002.

[4]结城浩.Java多线程设计模式[M].北京:中国铁道出版社,2005.

上一篇:基于ARM-linux的交叉编译环境的创建 下一篇:编辑框中的文本查找与替换设计