Java中finalize()的另類用法
Java中finalize()的另類用法,做過JAVA編程的都知道,在JAVA中有一種垃圾收集器的機(jī)制,當(dāng)它運(yùn)行時(shí)(通常在系統(tǒng)內(nèi)存低到一定限度時(shí)自動(dòng)運(yùn)行),會(huì)回收不再使用的對(duì)象所占用的內(nèi)存,所以,在JAVA程序中,我們通常只考慮創(chuàng)建對(duì)象,而從不關(guān)心對(duì)象的清除。Finalize()是JAVA為類提供的一種特殊方法。
垃圾收集器的工作過程大致是這樣的:一旦垃圾收集器準(zhǔn)備好釋放無用對(duì)象占用的存儲(chǔ)空間,它首先調(diào)用那些對(duì)象的finalize()方法,然后才真正回收對(duì)象的內(nèi)存。通過使用finalize(),就可以在垃圾收集器運(yùn)行期間進(jìn)行一些特殊的工作。下面一例就說明了finalize()的一種巧妙用法。
現(xiàn)在的商業(yè)應(yīng)用系統(tǒng)越來越多的采用WEB形式。在WEB形式應(yīng)用中,每一次頁(yè)面訪問是獨(dú)立的,前后不相關(guān)聯(lián),哪怕多個(gè)用戶在同一時(shí)刻訪問應(yīng)用的同一個(gè)頁(yè)面,用戶相互之間也是不知道的。如果想要檢查當(dāng)前有哪些用戶正在使用系統(tǒng)(如準(zhǔn)備恢復(fù)數(shù)據(jù)備份或進(jìn)行系統(tǒng)升級(jí)時(shí),系統(tǒng)管理員都很希望知道這些信息),該怎么辦呢? 基于Servlet、Jsp技術(shù)的WEB服務(wù)器提供了隱含的Session、Application對(duì)象,利用它可以幫開發(fā)者實(shí)現(xiàn)一些信息的持續(xù)保存和共享。當(dāng)用戶訪問一個(gè)WEB應(yīng)用時(shí),WEB服務(wù)器會(huì)自動(dòng)創(chuàng)建一個(gè)Session對(duì)象,該對(duì)象可以供用戶在會(huì)話期內(nèi)在應(yīng)用的所有頁(yè)面中共享數(shù)據(jù); Application是WEB應(yīng)用的一個(gè)全局對(duì)象。利用Session、Application對(duì)象,可以達(dá)到跟蹤所有用戶信息的目的。
當(dāng)用戶打開瀏覽器開始請(qǐng)求WEB應(yīng)用的登錄頁(yè)面時(shí),WEB服務(wù)即為該客戶創(chuàng)建一個(gè)session,此后,在session的timeout時(shí)間內(nèi),該客戶都使用這個(gè)session(timeout時(shí)間可設(shè)置,如Tomcat服務(wù)器是在各應(yīng)用的web.xml文件中設(shè)置)。如果使用IE瀏覽器, Session與客戶IP地址、客戶程序進(jìn)程ID所共同標(biāo)識(shí)的連接有對(duì)應(yīng)關(guān)系,相同IP地址、相同進(jìn)程的窗口(如通過IE-文件-新建-窗口打開的新窗口)具有同一個(gè)session,所以session可用于標(biāo)識(shí)各個(gè)獨(dú)立的客戶應(yīng)用連接。
下面是一個(gè)樣例:
為了方便處理,先建一個(gè)簡(jiǎn)單類(user)用來表達(dá)用戶信息及存放sessionId:
- package com;
- public class user {
- public String name="";
- public String sessionId="";
- }
另一個(gè)類(testSession)用于處理用戶的login、logout等動(dòng)作信息,使系統(tǒng)可以跟蹤當(dāng)前連接的用戶信息。
- package com;
- import java.util.Vector;
- import com.user;
- public class testSession {
- public user User;
- private Vector vsid;
- public testSession()
- {
- User=new user();
- }
- public boolean verify(String username,String password)
- throws Exception //驗(yàn)證用戶/密碼
- {
- return true;
- }
- public void setSessionVar(String sesid,Vector sid) {
- this.User.sessionId=sesid;
- this.vsid=sid;
- }
- private static synchronized void addappses(user puser,
- Vector pvsid) { //記錄一個(gè)新連接的用戶
- int pos=-1;
- user l_user;
- if (puser==null || pvsid==null)
- return;
- for(int i=0;i
- l_user=(user)pvsid.get(i);
- if(l_user.sessionId.equals(puser.sessionId)){
- pos=i;
- break;
- }
- }
- if(pos==-1){
- pvsid.add(puser);
- }
- else{
- pvsid.set(pos,puser);
- }
- }
- private static synchronized void removeappses(user puser,
- Vector pvsid) { //移除一個(gè)退出的用戶
- int pos=-1;
- user l_user;
- if (puser==null || pvsid==null)
- return;
- for(int i=0;i
- l_user=(user)pvsid.get(i);
- if(l_user.sessionId.equals(puser.sessionId)){
- pos=i;
- break;
- }
- }
- if(pos!=-1){
- pvsid.remove(pos);
- }
- }
- protected void finalize() {
- this.removeappses(this.User,this.vsid);
- }
- public boolean login(String username) throws Exception
- { //處理登錄
- this.User.name=username;
- this.addappses(this.User,this.vsid);
- return true;
- }
- public boolean logout() throws Exception
- { //處理注銷
- this. finalize();
- this.User=null;
- this.vsid=null;
- return true;
- }
- }
每一個(gè)用戶均建立一個(gè)testSession對(duì)象,來保存該用戶的信息。為了對(duì)類testSession進(jìn)行說明,必須同時(shí)引人另一個(gè)文件logintest.jsp。這個(gè)用于示例的JSP文件提供一個(gè)簡(jiǎn)單的界面進(jìn)行登錄、注銷處理。文件內(nèi)容如下:
- <%@ page import=" com.testSession,
- java.util.Vector"%>
- <%@page contentType="text/html;charset=GBK" %>
- <% request.setCharacterEncoding(response.
- getCharacterEncoding());%>
- <%
- String actionType=request.getParameter("actiontype");
- String actionResult="";
- if(actionType!=null) {
- if(actionType.equals("login")){ // -1-
- String userName=request.getParameter("username");
- if(userName==null || userName.equals("")){
- ;
- }
- else{
- String password=request.getParameter("password");
- if(password==null)
- password="";
- testSession ts=
- (testSession)session.getAttribute("testSession");
- if(ts!=null) { //-1.1-
- session.removeAttribute("testSession");
- if( !ts.User.name.equals(""))
- ts.logout();
- }
- ts=new testSession();
- if(!ts.verify(userName,password)) {
- //驗(yàn)證用戶與密碼,看是否合法用戶
- actionResult="login fail";
- //非法用戶,顯示錯(cuò)誤信息
- }
- else{ //驗(yàn)證成功
- session.setAttribute("testSession",ts);
- Vector app_vts=
- (Vector)application.getAttribute("app_vts");
- if(app_vts==null) {
- app_vts=new Vector();
- application.setAttribute("app_vts",app_vts);
- }
- ts.setSessionVar(session.getId(),app_vts);
- ts.login(userName);
- actionResult=userName+" login success";
- }
- }
- }
- if(actionType.equals("logout")){
- testSession ts=
- (testSession)session.getAttribute("testSession");
- if(ts!=null) {
- session.removeAttribute("testSession");
- if( !ts.User.name.equals("")){ //-2-
- actionResult=ts.User.name;
- ts.logout();
- }
- session.invalidate();
- }
- actionResult=actionResult+" logout success";
- }
- }
- else
- actionResult="null";
- %>
【編輯推薦】