17
四四四四四四四四四四 http://www.scemi.com 4.2 四四四四四四四四四四 四四四 四四四四四 四四四 13684285460 [email protected] 156638267 Tel: Email: QQ:

4.2 通讯服务模块线程之间传递信息

Embed Size (px)

DESCRIPTION

4.2 通讯服务模块线程之间传递信息. 信息工程系 向模军. Tel: Email: QQ:. 13684285460 [email protected] 156638267. 1 任务引入. - PowerPoint PPT Presentation

Citation preview

Page 1: 4.2 通讯服务模块线程之间传递信息

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

信息工程系 向模军[email protected]

Tel:Email: QQ:

Page 2: 4.2 通讯服务模块线程之间传递信息

2/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

1 任务引入

线程之间不是孤立的,线程之间往往要进行信息交换,由于信息的多样性,对不同信息的处理方式是不同的,通常在基于 TCP 的聊天通讯过程中,通信信息被封装在一个消息对象中,要实现消息对象在网络上的传输,该消息类必须能够被“序列化”。监听线程在接收到消息对象后,将消息对象交给一个服务线程处理,服务线程根据消息对象的分类,有两种处理方式,对“命令类”消息,服务线程直接处理,对“聊天消息”,服务线程做日志记录,并将该消息对象添加到一个消息对象队列中,消息接收线程从消息对象队列中取出消息对象,并做相应的处理。

Page 3: 4.2 通讯服务模块线程之间传递信息

3/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

2 任务讨论

用于线程间传递信息的中间类设计;如何传递中间类。

Page 4: 4.2 通讯服务模块线程之间传递信息

4/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 对象流

对象的持续性( Persistence )能够纪录自己的状态以便将来再生的能力,叫对象的持续性。

对象的持续性通常应用在网络传输、介质存储等方面。对象的持续性通过串行化完成。

对象的串行化( Serialization )对象通过写出描述自己状态的的数值来记录自己的过程叫串行

化。串行化的主要任务是写出对象实例变量的数值,如果变量是另一个对象的引用,则引用的对象也要串行化。这个过程是递归的。

对象流概念能够输入输出对象的流称为对象流。可以将对象串行化后通过

对象输入输出流写入文件或传送到其它地方。

Page 5: 4.2 通讯服务模块线程之间传递信息

5/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 用管道流实现线程间的通信

管道用来把一个程序、线程和代码块的输出连接到另一个程序、线程和代码块的输入。 java.io 中提供了类 PipedInputStream 和PipedOutputStream 作为管道的输入 / 输出流。

线程 1 PipedOutputStream PipedInputStream

输出流 outStream 输入流 inStream

线程 2

主类 Pipethread

辅类myWriter

线程类

辅类myReader

线程类

管道流

将数据写到输出流

从输入流中读数据

输出流作为参数传给myWriter

输入流作为参数传给myReader

Page 6: 4.2 通讯服务模块线程之间传递信息

6/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 用管道流实现线程间的通信

import java.io.*;class myWriter extends Thread { private PipedOutputStream outStream; // 将数据输出 private String messages[] = {"Monday", "Tuesday ", "Wednsday",

"Thursday", "Friday", "Saturday", "Sunday"}; public myWriter(PipedOutputStream o) { outStream = o; } public void run() { try { ObjectOutputStream p = new ObjectOutputStream(outStream); for (int i = 0; i < messages.length; i++) { System.out.println("Write:" + messages[i]); p.writeObject(messages[i]); p.flush(); } p.close(); p = null; } catch (IOException e) {} }}

写线程

Page 7: 4.2 通讯服务模块线程之间传递信息

7/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 用管道流实现线程间的通信import java.io.*;class myReader extends Thread { private PipedInputStream inStream; // 从中读数据 public myReader(PipedInputStream i) { inStream = i; } public void run() { Object data; ObjectInputStream r; boolean reading =

true; try { r = new ObjectInputStream(inStream); while (reading && r != null) { data = r.readObject(); if (data != null) { System.out.println("Read: " + data.toString()); } else { reading = false; } } r.close(); } catch (IOException e) {} catch (ClassNotFoundException e) {} }}

读线程

Page 8: 4.2 通讯服务模块线程之间传递信息

8/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 用管道流实现线程间的通信import java.io.*;public class Pipethread { public static void main(String args[]) { Pipethread thisPipe = new Pipethread();

thisPipe.process(); } public void process() { PipedInputStream inStream; PipedOutputStream

outStream; try{ outStream = new PipedOutputStream(); inStream = new PipedInputStream(outStream); new myWriter( outStream ).start(); new myReader( inStream ).start(); }catch( IOException e ){ } }}

利用管道流的主线程

Page 9: 4.2 通讯服务模块线程之间传递信息

9/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 通过一个中间类在线程间传递信息

线程 2线程 1 中间类m

s s

m.write(s)s=m.read()

write() read()

管道流方式自动解决了写线程和读线程之间的互斥共享问题,而自己定义的中间类必须自己解决写线程和读线程之间的互斥共享问题。

Page 10: 4.2 通讯服务模块线程之间传递信息

10/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 通过一个中间类在线程间传递信息

public class shareObject { private String value=""; public shareObject() { } public void write(String str)

{this.value=str;} public String read(){return this.value;}}

中间类

Page 11: 4.2 通讯服务模块线程之间传递信息

11/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 通过一个中间类在线程间传递信息

class myWriter extends Thread { private shareObject obj = null; private String messages[] = {"Monday", "Tuesday ", "Wednsday",

"Thursday","Friday", "Saturday", "Sunday"}; public myWriter(shareObject obj) { this.obj = obj; } public void run() { try {for (int i = 0; i < messages.length; i++) { System.out.println("Write:" + messages[i]); obj.write(messages[i]); sleep( 400); } } catch (InterruptedException e) {} obj.write("end"); System.out.println(" 写线程结束 "); }}

写线程

Page 12: 4.2 通讯服务模块线程之间传递信息

12/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

3 通过一个中间类在线程间传递信息

读线程

public class myReader extends Thread { private shareObject obj = null; public myReader(shareObject obj) { this.obj =

obj; } public void run() { try {String value = obj.read(); while (!value.trim().equals("end")) { if (value.trim().length() > 0) System.out.println("Reader:" + value); sleep(500); value=obj.read(); } } catch (InterruptedException e) {} System.out.println(" 读线程结束 "); }}

Page 13: 4.2 通讯服务模块线程之间传递信息

13/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

4 任务实施

在 JBuilder 中新建项目。在项目中建立以下 6 个类。

1. TransData 类:用于网络传输的“消息”,序列化。2. DataCache 类:“消息队列”,存储需要处理的 TransData 实例。3. listenThread 线程类:模拟网络通讯,不断接收不同类型的“消

息”,并创建、启动 serviceThread 线程处理接收到的“消息”。4. serviceThread 线程类:处理 comand 型的“消息”,将其他

“消息”加入“消息队列”。5. messageManager 线程类:处理“消息队列”中的“消息”。6. mainThread 类:主程序,启动 listenThread 和 mesageManager

线程。

Page 14: 4.2 通讯服务模块线程之间传递信息

14/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

5 任务点评

• messageManager 是单线程,与 listenThread 线程一起启动。• serviceThread 是多线程, listenThread 每产生一个“消息”,

就创建并启动一个 serviceThread 线程。• DataCache 是一个中间类,负责 messageManager 线程与

serviceThread 线程之间传递信息。

Page 15: 4.2 通讯服务模块线程之间传递信息

15/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

6 试一试 练一练

• 试改写 DataCache ,使 messageManager 线程在读取“消息队列”期间被“阻塞”一会儿。观察程序输出有何变化。

Page 16: 4.2 通讯服务模块线程之间传递信息

16/17

四川机电职业技术学院http://www.scemi.com

4.2 通讯服务模块线程之间传递信息

7 课外拓展

• 收集资料,了解“对象的持续性 ”应用环境。

Page 17: 4.2 通讯服务模块线程之间传递信息

四川机电职业技术学院http://www.scemi.com