洞察探讨小游戏SDK接入的最佳实践以及对企业跨平台开发的优势
818
2022-08-30
Tomcat 源码分析 (Tomcat的Session管理之管理过期Session) (十二)
文章目录
0.前记1.判断session是否有效2.处理Session过期
0.前记
在之前的文章中通过doGetSession()获取Session
protected Session doGetSession(boolean create) { // There cannot be a session if no context has been assigned yet Context context = getContext(); if (context == null) { return (null); } //11 if ((session != null) && !session.isValid()) { session = null; } if (session != null) { return (session); } //省略}
1.判断session是否有效
判断Session 是否有效
/** * Return the isValid
flag for this session. */@Overridepublic boolean isValid() { //如果是无效 返回无效 if (!this.isValid) { return false; } //如果已经过期了,就返回有效 if (this.expiring) { return true; } //该session的访问次数大于0 有效session if (ACTIVITY_CHECK && accessCount.get() > 0) { return true; } //如果 允许的最大闲置时间大于0,也就是存在最大闲置时间 if (maxInactiveInterval > 0) { //现在 long timeNow = System.currentTimeMillis(); //空闲时间 int timeIdle; if (LAST_ACCESS_AT_START) { timeIdle = (int) ((timeNow - lastAccessedTime) / 1000L); } else { timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L); } //如果空闲时间 大于允许的最大闲置时间,那么就将session置为过期 if (timeIdle >= maxInactiveInterval) { expire(true); } } return this.isValid;}
2.处理Session过期
session过期的话
public void expire(boolean notify) { //再次检查 isValid属性因为有可能已经被别的线程置为无效,也意味着该session已经被过期处理 if (!isValid) return; //锁定该session对象 synchronized (this) { //再次检查 if (expiring || !isValid) return; if (manager == null) return; //将expiring 设置为过期 expiring = true; // Notify interested application event listeners // FIXME - Assumes we call listeners in reverse order Context context = (Context) manager.getContainer(); ClassLoader oldTccl = null; if (context.getLoader() != null && context.getLoader().getClassLoader() != null) { oldTccl = Thread.currentThread().getContextClassLoader(); if (Globals.IS_SECURITY_ENABLED) { PrivilegedAction
代码内部一再检查isValid属性, 理论上同一个用户只会同时开一个线程, 也就是同时只有一个线程更改session属性。
再次检查属性是为了防止其他线程修改, 因为Catalina内部有一个定时线程不停的跑过期session, 为了让很多不调用getSession()的方法的session不销毁。
StandardManager.backgroundProcess()做一些周期性任务
@Override public void backgroundProcess() { count = (count + 1) % processExpiresFrequency; if (count == 0) processExpires(); }
处理expires()
ManagerBase.processExpires()
public void processExpires() { long timeNow = System.currentTimeMillis(); Session sessions[] = findSessions(); int expireHere = 0 ; if(log.isDebugEnabled()) log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length); for (int i = 0; i < sessions.length; i++) { //调用isValid() 处理过期session if (sessions[i]!=null && !sessions[i].isValid()) { expireHere++; } } long timeEnd = System.currentTimeMillis(); if(log.isDebugEnabled()) log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere); processingTime += ( timeEnd - timeNow );}
不管是主动getSession()还是后台周期任务处理,都会调用isValid()方法处理过期session。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~