📄 第六章 租用(leasing).htm
字号:
<html>
<head>
<title>新时代软件教程:操作系统 主页制作 服务器 设计软件 网络技术 编程语言 文字编辑</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
<!--
body, table {font-size: 9pt; font-family: 宋体}
a {text-decoration:none}
a:hover {color: red;text-decoration:underline}
.1 {background-color: rgb(245,245,245)}
-->
</style>
</head>
<p align="center"><script src="../../1.js"></script></a>
<p align="center"><big><strong>第六章 租用(Leasing)</strong></big></p>
<p>Leasing是在两个应用程序之间以某种同意的方式访问资源的一种机制。
<P>1、 Leases<BR>
Leases是要求一段时间。在jini中,其主要作用是要求保存在lookup locator上的服务拷贝保留的时间。服务要求时间是在类ServiceRegistrar中的方法register中完成。
时间的两个特殊值是:
<pre><code>
(1) Lease.ANY --- 服务让locator来决定保留的时间
(2) Lease.FOREVER ---- 请求服务永不过期
</code></pre>
Locator扮演lease的审批者,决定lease将保留多长时间。(sun的lookup locator通常设lease的时间为五秒。)一旦签定了lease,lookup locator就要保证对服务的请求在该段时间内是可用的。服务端可通过对象ServiceRegistration的方法
getLease()得到lease。Lease对象的主要方法如下:
<pre><code>
package net.jini.core;public interface Lease {
void cancel() throws
UnknownLeaseException,
java.rmi.RemoteException;
long getExpiration();
void renew(long duration) throws
LeaseDeniedException,
UnknownLeaseException,
java.rmi.RemoteException;
}
</code></pre>
方法getExpiration()的返回值是以从新纪元开始的毫秒数(和 System.currentTimeMillis()相同)。
服务可以通过cancel()忽略它的lease。服务所见的lease是代理,它和lookup locator通信并忽略其上的lease。当一个lease过期了,就悄悄地被忽略了。就是说,lease的审批者lookup locator并不通知lease的持有者service租界已经过期了。如果服务想让租界(lease)继续,它可以在租界
过期前调用方法renew()。
<P>2、 LeaseRenewalManager
<P>Jini 支持一个类LeaseRenewalManager用来在适当的时间调用方法renew()。
<pre><code>
package com.sun.jini.lease;
public Class LeaseRenewalManager {
public LeaseRenewalManager();
public LeaseRenewalManager(Lease lease,
long expiration,
LeaseListener listener);
public void renewFor(Lease lease, long duration,
LeaseListener listener);
public void renewUntil(Lease lease,
long expiration,
LeaseListener listener);
// etc}
</code></pre>
它管理租借的集合,可以有构造函数或用方法renewFor()或renewUntil()加入。这里使用的时间是以毫秒
为单位的。变量expiration时间是从新纪元开始,而duration时间是从现在开始的。当lookup locator决定不更新lease时就会产生一个例外。这会被renewal manager捕捉到,并调用监听器的以LeaseRenewalEvent为参数的方法notify()。如果应用程序的租借被拒
绝了,这可以让它做补救工作。其中listener可以是null。
你要小心的设置renewFor()方法中的duration。如果你想让服务永远有效,可以用Lease.FOREVER。但是,
目前执行仅仅是将duration加到System.currentTimeMillis()上,这可能得到负值。所以这样就不会更新。
严格的讲,在调用方法renewFor()前,应该保证duration + System.currentTimeMillis() > 0。
<pre><code>
package option3;
import java.rmi.Naming;
import java.net.InetAddress;
import net.jini.discovery.LookupDiscovery;
import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceRegistration;
import net.jini.core.lease.Lease;
import java.rmi.RMISecurityManager;
import com.sun.jini.lease.LeaseRenewalManager;
import com.sun.jini.lease.LeaseListener;
import com.sun.jini.lease.LeaseRenewalEvent;
/** * FileClassifierServerLM.java *
* Created: Wed Mar 17 14:23:44 1999
* @author Jan Newmarch
* @version
*/
public class FileClassifierServerLM implements DiscoveryListener, LeaseListener {
// this is just a name - can be anything
// impl object forces search for Stub
static final String serviceName = "FileClassifier";
protected FileClassifierImpl impl;
protected FileClassifierProxy proxy;
protected LeaseRenewalManager leaseManager = new LeaseRenewalManager();
public static void main(String argv[]) {
new FileClassifierServerLM();
}
public FileClassifierServerLM() {
try {
impl = new FileClassifierImpl();
} catch(Exception e) {
System.err.println("New impl: " + e.toString());
System.exit(1);
}
// register this with RMI registry
System.setSecurityManager(new RMISecurityManager());
try {
Naming.rebind(serviceName, impl);
} catch(java.net.MalformedURLException e) {
System.err.println("Binding: " + e.toString());
System.exit(1);
} catch(java.rmi.RemoteException e) {
System.err.println("Binding: " + e.toString());
System.exit(1);
}
System.out.println("bound");
// find where we are running
String address = null;
try {
address = InetAddress.getLocalHost().getHostName();
} catch(java.net.UnknownHostException e) {
System.err.println("Address: " + e.toString());
System.exit(1); }
String registeredName = "//" + address + "/" + serviceName;
// make a proxy that knows the service address
proxy = new FileClassifierProxy(registeredName);
// now continue as before
LookupDiscovery discover = null;
try {
discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
} catch(Exception e) {
System.err.println(e.toString());
System.exit(1);
}
discover.addDiscoveryListener(this);
System.out.println("waiting...");
// stay around long enough to receive replies
try {
Thread.currentThread().sleep(10000000L);
} catch(java.lang.InterruptedException e) {
// do nothing
}
}
public void discovered(DiscoveryEvent evt) {
ServiceRegistrar[] registrars = evt.getRegistrars();
for (int n = 0; n < registrars.length; n++) {
ServiceRegistrar registrar = registrars[n];
// export the proxy service
ServiceItem item = new ServiceItem(null, proxy, null);
ServiceRegistration reg = null;
try {
reg = registrar.register(item, 20000L);
} catch(java.rmi.RemoteException e) {
System.err.println("Register exception: " + e.toString());
}
try {
System.out.println("Service registered at " +
registrar.getLocator().getHost());
System.out.println("Lease granted for " +
(reg.getLease().getExpiration()
- System.currentTimeMillis()));
} catch(Exception e) { }
leaseManager.renewFor(reg.getLease(), 1000000L, this);
}
}
public void discarded(DiscoveryEvent evt) { }
public void notify(LeaseRenewalEvent evt) {
System.out.println("Expired " + evt.toString());
}
} // FileClassifierServerLM
</code></pre>
</table>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -