我一直在阅读有关RMI的Java教程。我喜欢这里概述的用于实现远程接口的方法:
http://download.oracle.com/javase/tutorial/rmi/implementing.html
我想知道的是两件事:
1)关于前面提到的链接中概述的executeTask
方法,如果ComputeEngine只是调用Task的execute方法,那么这个设计如何允许远程对象(任务)访问某种全局状态?
2)这种设计是否适合多线程环境?
非常感谢。
答案 0 :(得分:1)
广告。 1:请注意,远程客户端不了解ComputeEngine
类,只知道Compute
接口。此外,服务器实现可能会完全更改,但如果接口没有更改,客户端不应该注意到。如果要将一些上下文传递给来自远程客户端的任务,请在界面层上执行:
public class ComputeEngine implements Compute {
private GlobalContext globalContext = //...
public <T> T executeTask(Task<T> t) {
return t.execute(globalContext);
}
这样,每个任务都可以访问globalContext
并确切地知道globalContext
的内容(服务器功能是什么,上下文)。 GlobalContext
将是一个JavaBean或更可能是一些服务接口。
在客户端,它可能看起来像这样
Compute compute = //obtain RMI client stub somehow
compute.executeTask(new Task<String>() {
public String execute(GlobalContext globalContext) {
//Note that this code is executed on the server and
//getFoo() is implemented on the server side. We only know its interface
globalContext.getFoo();
//...
}
}
广告。 2:它将工作与多个客户端同时调用服务。但是,您可以通过线程安全的方式实现服务器。您在线程安全中提到的教程示例,但我使用GlobalContext
的代码可能不是。请注意,多个客户端将同时使用同一个globalContext
实例,这可能但不一定会导致某些问题。这可能是最有趣的部分。
最后记住,从远程客户端接收未知Task
并在服务器上运行它是非常令人印象深刻的,但不太安全。