- 浏览: 10419 次
最新评论
JAVA RMI线程模型及内部实现机制
2010年06月07日
JAVA RMI是JAVA分布式结构的基础。远程对象的通信过程中,RMI使用标准机制:stub和skeleton。远程对象的stub担当远程对象的客户本地代表或代理人角色,调用程序将调用本地stub的方法,而本地stub将负责执行对远程对象的方法调用。在RMI中,远程对象的stub与该远程对象所实现的远程接口集相同。调用stub的方法时将执行下列操作:
(1) 初始化与包含远程对象的远程虚拟机的连接;
(2) 对远程虚拟机的参数进行编组-传输参数;
(3) 等待远程方法调用结果;
(4) 解编(读取)返回值或返回的异常;
(5) 将值返回给调用程序。
为了向调用程序展示比较简单的调用机制,stub将参数的序列化和网络级通信等细节隐藏了起来。在远程虚拟机中,每个远程对象都可以有相应的skeleton。skeleton负责将调用分配给实际的远程对象实现。它在接收方法调用时执行下列操作:
(1) 解编(读取)远程方法的参数;
(2) 调用实际远程对象实现上的方法;
(3) 将结果(返回值或异常)编组(写入并传输)给调用程序。
stub和skeleton由rmic编译器生成。在最新的JDK中,不需要手工生产stub和skeleton,用动态代理生成的Proxy代替了stub,而skeleton则取消了。
我们可以查看源代码来了解RMI的内部实现。Server端调用UnicastRemoteObject的export方法输出远程对象,export方法会在一个线程里监听某个TCP端口上的方法调用请求: public void exportObject(Target target) throws RemoteException { // other code while (true) { ServerSocket myServer = server; if (myServer == null) return; Throwable acceptFailure = null; final Socket socket; try { socket = myServer.accept(); /* * Find client host name (or "0.0.0.0" if unknown) */ InetAddress clientAddr = socket.getInetAddress(); String clientHost = (clientAddr != null ? clientAddr.getHostAddress() : "0.0.0.0"); /* * Spawn non-system thread to handle the connection */ Thread t = (Thread) java.security.AccessController.doPrivileged ( new NewThreadAction(new ConnectionHandler(socket, clientHost), "TCP Connection(" + ++ threadNum + ")-" + clientHost, true, true)); t.start(); } catch (IOException e) { acceptFailure = e; } catch (RuntimeException e) { acceptFailure = e; } catch (Error e) { acceptFailure = e; } } // other code } 上面的代码已被修改以展示主要的要点,Server端就是在ServerSocket的accept方法上面监听到来的请求,如果有新的方法调用请求到来,Server产生一个单独的线程来处理新接收的请求: public void dispatch(Remote obj, RemoteCall call) throws IOException { // positive operation number in 1.1 stubs; // negative version number in 1.2 stubs and beyond... int num; long op; try { // read remote call header ObjectInput in; try { in = call.getInputStream(); num = in.readInt(); if (num >= 0) { if (skel != null) { oldDispatch(obj, call, num); return; } else { throw new UnmarshalException( "skeleton class not found but required " + "for client version"); } } op = in.readLong(); } catch (Exception readEx) { throw new UnmarshalException("error unmarshalling call header", readEx); } /* * Since only system classes (with null class loaders) will be on * the execution stack during parameter unmarshalling for the 1.2 * stub protocol, tell the MarshalInputStream not to bother trying * to resolve classes using its superclasses's default method of * consulting the first non-null class loader on the stack. */ MarshalInputStream marshalStream = (MarshalInputStream) in; marshalStream.skipDefaultResolveClass(); Method method = (Method) hashToMethod_Map.get(new Long(op)); if (method == null) { throw new UnmarshalException("invalid method hash"); } // if calls are being logged, write out object id and operation logCall(obj, method); // unmarshal parameters Class[] types = method.getParameterTypes(); Object[] params = new Object[types.length]; try { unmarshalCustomCallData(in); for (int i = 0; i 结果写入到输出流中:marshalValue(rtype, result, out)。一个方法调用就执行完成了。
Client端请求一个远程方法调用时,先建立连接:Connection conn = ref.getChannel().newConnection(),然后发送方法参数: marshalValue(types[i], params[i], out),再发送执行方法请求:call.executeCall(),最后得到方法的执行结果:Object returnValue = unmarshalValue(rtype, in),并关闭接:
ref.getChannel().free(conn, true)。 public Object invoke(Remote obj, java.lang.reflect.Method method, Object[] params, long opnum) throws Exception { if (clientRefLog.isLoggable(Log.VERBOSE)) { clientRefLog.log(Log.VERBOSE, "method: " + method); } if (clientCallLog.isLoggable(Log.VERBOSE)) { logClientCall(obj, method); } Connection conn = ref.getChannel().newConnection(); RemoteCall call = null; boolean reuse = true; /* If the call connection is "reused" early, remember not to * reuse again. */ boolean alreadyFreed = false; try { if (clientRefLog.isLoggable(Log.VERBOSE)) { clientRefLog.log(Log.VERBOSE, "opnum = " + opnum); } // create call context call = new StreamRemoteCall(conn, ref.getObjID(), -1, opnum); // marshal parameters try { ObjectOutput out = call.getOutputStream(); marshalCustomCallData(out); Class[] types = method.getParameterTypes(); for (int i = 0; i socket, clientHost), "TCP Connection(" + ++ threadNum + ")-" + clientHost, true, true)); 在JDK1.6之后,RMI使用线程池来处理新接收的远程方法调用请求-ThreadPoolExecutor。
下面是一个简单的RMI程序的执行线程抓图,我们可以更好的了解RMI的线程机制。这个简单的RMI程序是服务端有一个远程方法实现,一个客户端同时请求执行这个远程方法100次。在JDK1.5中执行时生成的线程如下图所示,每个方法调用请求都是在一个单独的线程里执行,即 A Thread per Request。
在JDK1.6中执行时生成的线程如下图所示,这些线程都是在ThreadPoolExecutor线程池中执行的。
在JDK1.6中,RMI提供了可配置的线程池参数属性:
sun.rmi.transport.tcp.maxConnectionThread - 线程池中的最大线程数量
sun.rmi.transport.tcp.threadKeepAliveTime - 线程池中空闲的线程存活时间
发表评论
-
[.net] 关于.net线程问题总结(二)
2012-01-20 00:50 615[.net] 关于.net线程问题总结(二) 2011年01 ... -
多进程与多线程区别
2012-01-20 00:50 579多进程与多线程区别 20 ... -
delphi 文件下载汇总
2012-01-20 00:50 932delphi 文件下载汇总 2011年03月22日 现在 ... -
电脑高手应用技巧荟萃(电脑知识二十六)
2012-01-17 01:08 594电脑高手应用技巧荟萃(电脑知识二十六) 2010年12月07 ... -
电脑常见问题2
2012-01-17 01:08 627电脑常见问题2 2010年10 ... -
(9.26更新 老机福音,再创经典)Ghost_XP_战神 V9.5 老机优化版
2012-01-17 01:07 1049(9.26更新 老机福音,再创经典)Ghost_XP_战神 V ... -
安卓新手成长日记之Andriod系统基础知识普及
2012-01-17 01:07 629安卓新手成长日记之Andriod系统基础知识普及 2011年 ... -
什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?
2012-01-15 19:49 640什么是CGI、FastCGI、PHP-CG ... -
Android开机启动流程,IT爱好者必看
2012-01-15 19:49 501Android开机启动流程,IT爱好者必看 2011年11月 ... -
IP组播技术综述二
2012-01-15 19:49 551IP组播技术综述二 2011 ... -
Java加密和数字签名 5数字证书
2012-01-15 19:49 572Java加密和数字签名 5数 ... -
MySql 常用命令
2012-01-11 12:02 537MySql 常用命令 2011年07 ... -
情人节后的 JSF PrimeFaces2.0 更完美了!
2012-01-11 12:02 549情人节后的 JSF PrimeFaces2.0 更完美了! ... -
JS 动态添加事件
2012-01-11 12:02 500JS 动态添加事件 2011年07月01日 转:http ... -
转义符号启示-坚持-iteye技术网站
2012-01-11 12:02 349转义符号启示-坚持-iteye技术网站 2011年07月01 ... -
一个简单的异步http连接器iteye技术网站
2012-01-11 12:02 496一个简单的异步http连接器iteye技术网站 2011年0 ...
相关推荐
java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...
Java语言的发展及相关技术的介绍,Java技术和平台在网络计算及电子商务中的应用介绍; ■ Java语言的基础知识:Java语言的主要特点,设计思想,Java虚拟机,垃圾回收机制,安全性的保证机制; ■ Java语言的...
用Java实现一个UDP通信模型 pdf 用Java实现一个Socket通信模型 pdf 用Java实现网络通讯 pdf 用JAVA实现基于TCP的SOCKET编程 pdf 用Java实现基于TCPIP协议的网络通信程序 pdf 一种基于JAVA多线程的即时显示策略 ...
java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...
■ Java语言的发展及相关技术的介绍,Java技术和平台在网络计算及电子商务中的应用介绍; ■ Java语言的基础知识:Java语言的主要特点,设计思想,Java虚拟机,垃圾回收机制,安全性的保证机制; ■ Java语言...
java清华版教程, ■ Java语言的发展及相关技术的介绍,Java技术和平台在网络计算及电子商务中的应用介绍; ■ Java语言的基础知识:Java语言的主要特点,设计思想,Java虚拟机,垃圾回收机制,安全性的保证机制...
java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...
java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中...
■ Java语言的发展及相关技术的介绍,Java技术和平台在网络计算及电子商务中的应用介绍; ■ Java语言的基础知识:Java语言的主要特点,设计思想,Java虚拟机,垃圾回收机制,安全性的保证机制; ■ Java...
java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中...
用Java实现一个UDP通信模型.pdf 用Java实现一个Socket通信模型.pdf 用Java实现网络通讯.pdf 用JAVA实现基于TCP的SOCKET编程.pdf 用Java实现基于TCPIP协议的网络通信程序.pdf 一种基于JAVA多线程的即时显示策略....
★ 第六讲 Java的线程和Java Applet ◇课前索引 ◇6.1 线程简介 ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 ...
java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中...
★ 第六讲 Java的线程和Java Applet ◇课前索引 ◇6.1 线程简介 ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 ...
以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。 public class ThreadTest1{ private int j; public static void main(String args[]){ ThreadTest1 tt=new ThreadTest1(); Inc inc=tt.new Inc(); ...
java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中...
★ 第六讲 Java的线程和Java Applet ◇课前索引 ◇6.1 线程简介 ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 ...
★ 第六讲 Java的线程和Java Applet ◇课前索引 ◇6.1 线程简介 ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 ...