javaWeb学习总结(11)- 监听器(Listener)在开发中的应用
监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用
一、统计当前在线人数
在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听器技术来实现这个功能了。
- package me.gacl.web.listener;
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpSessionEvent;
- import javax.servlet.http.HttpSessionListener;
- /**
- * @ClassName: OnLineCountListener
- * @Description: 统计当前在线用户个数
- * @author: 孤傲苍狼
- * @date: 2014-9-10 下午10:01:26
- *
- */
- public class OnLineCountListener implements HttpSessionListener {
- @Override
- public void sessionCreated(HttpSessionEvent se) {
- ServletContext context = se.getSession().getServletContext();
- Integer onLineCount = (Integer) context.getAttribute("onLineCount");
- if(onLineCount==null){
- context.setAttribute("onLineCount", 1);
- }else{
- onLineCount++;
- context.setAttribute("onLineCount", onLineCount);
- }
- }
- @Override
- public void sessionDestroyed(HttpSessionEvent se) {
- ServletContext context = se.getSession().getServletContext();
- Integer onLineCount = (Integer) context.getAttribute("onLineCount");
- if(onLineCount==null){
- context.setAttribute("onLineCount", 1);
- }else{
- onLineCount--;
- context.setAttribute("onLineCount", onLineCount);
- }
- }
- }
二、自定义Session扫描器
当一个Web应用创建的Session很多时,为了避免Session占用太多的内存,我们可以选择手动将这些内存中的session销毁,那么此时也可以借助监听器技术来实现。
- package me.gacl.web.listener;
- import java.util.Collections;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.ListIterator;
- import java.util.Timer;
- import java.util.TimerTask;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- import javax.servlet.http.HttpSession;
- import javax.servlet.http.HttpSessionEvent;
- import javax.servlet.http.HttpSessionListener;
- /**
- * @ClassName: SessionScanerListener
- * @Description: 自定义session扫描器
- * @author: 孤傲苍狼
- * @date: 2014-9-10 下午10:16:42
- *
- */
- public class SessionScanerListener implements HttpSessionListener,ServletContextListener {
- /**
- * @Field: list
- * 定义一个集合存储服务器创建的HttpSession
- * LinkedList不是一个线程安全的集合
- */
- /**
- * private List<HttpSession> list = new LinkedList<HttpSession>();
- * 这样写涉及到线程安全问题,SessionScanerListener对象在内存中只有一个
- * sessionCreated可能会被多个人同时调用,
- * 当有多个人并发访问站点时,服务器同时为这些并发访问的人创建session
- * 那么sessionCreated方法在某一时刻内会被几个线程同时调用,几个线程并发调用sessionCreated方法
- * sessionCreated方法的内部处理是往一个集合中添加创建好的session,那么在加session的时候就会
- * 涉及到几个Session同时抢夺集合中一个位置的情况,所以往集合中添加session时,一定要保证集合是线程安全的才行
- * 如何把一个集合做成线程安全的集合呢?
- * 可以使用使用 Collections.synchronizedList(List<T> list)方法将不是线程安全的list集合包装线程安全的list集合
- */
- //使用 Collections.synchronizedList(List<T> list)方法将LinkedList包装成一个线程安全的集合
- private List<HttpSession> list = Collections.synchronizedList(new LinkedList<HttpSession>());
- //定义一个对象,让这个对象充当一把锁,用这把锁来保证往list集合添加的新的session和遍历list集合中的session这两个操作达到同步
- private Object lock = new Object();
- @Override
- public void sessionCreated(HttpSessionEvent se) {
- System.out.println("session被创建了!!");
- HttpSession session = se.getSession();
- synchronized (lock){
- /**
- *将该操作加锁进行锁定,当有一个thread-1(线程1)在调用这段代码时,会先拿到lock这把锁,然后往集合中添加session,
- *在添加session的这个过程中假设有另外一个thread-2(线程2)来访问了,thread-2可能是执行定时器任务的,
- *当thread-2要调用run方法遍历list集合中的session时,结果发现遍历list集合中的session的那段代码被锁住了,
- *而这把锁正在被往集合中添加session的那个thread-1占用着,因此thread-2只能等待thread-1操作完成之后才能够进行操作
- *当thread-1添加完session之后,就把lock放开了,此时thread-2拿到lock,就可以执行遍历list集合中的session的那段代码了
- *通过这把锁就保证了往集合中添加session和变量集合中的session这两步操作不能同时进行,必须按照先来后到的顺序来进行。
- */
- list.add(session);
- }
- }
- @Override
- public void sessionDestroyed(HttpSessionEvent se) {
- System.out.println("session被销毁了了!!");
- }
- /* Web应用启动时触发这个事件
- * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
- */
- @Override
- public void contextInitialized(ServletContextEvent sce) {
- System.out.println("web应用初始化");
- //创建定时器
- Timer timer = new Timer();
- //每隔30秒就定时执行任务
- timer.schedule(new MyTask(list,lock), 0, 1000*30);
- }
- @Override
- public void contextDestroyed(ServletContextEvent sce) {
- System.out.println("web应用关闭");
- }
- }
- /**
- * @ClassName: MyTask
- * @Description:定时器要定时执行的任务
- * @author: 孤傲苍狼
- * @date: 2014-9-11 上午12:02:36
- *
- */
- class MyTask extends TimerTask {
- //存储HttpSession的list集合
- private List<HttpSession> list;
- //存储传递过来的锁
- private Object lock;
- public MyTask(List<HttpSession> list,Object lock){
- this.list = list;
- this.lock = lock;
- }
- /* run方法指明了任务要做的事情
- * @see java.util.TimerTask#run()
- */
- @Override
- public void run() {
- //将该操作加锁进行锁定
- synchronized (lock) {
- System.out.println("定时器执行!!");
- ListIterator<HttpSession> it = list.listIterator();
- /**
- * 迭代list集合中的session,在迭代list集合中的session的过程中可能有别的用户来访问,
- * 用户一访问,服务器就会为该用户创建一个session,此时就会调用sessionCreated往list集合中添加新的session,
- * 然而定时器在定时执行扫描遍历list集合中的session时是无法知道正在遍历的list集合又添加的新的session进来了,
- * 这样就导致了往list集合添加的新的session和遍历list集合中的session这两个操作无法达到同步
- * 那么解决的办法就是把"list.add(session)和while(it.hasNext()){//迭代list集合}"这两段代码做成同步,
- * 保证当有一个线程在访问"list.add(session)"这段代码时,另一个线程就不能访问"while(it.hasNext()){//迭代list集合}"这段代码
- * 为了能够将这两段不相干的代码做成同步,只能定义一把锁(Object lock),然后给这两步操作加上同一把锁,
- * 用这把锁来保证往list集合添加的新的session和遍历list集合中的session这两个操作达到同步
- * 当在执行往list集合添加的新的session操作时,就必须等添加完成之后才能够对list集合进行迭代操作,
- * 当在执行对list集合进行迭代操作时,那么必须等到迭代操作结束之后才能够往往list集合添加的新的session
- */
- while(it.hasNext()){
- HttpSession session = (HttpSession) it.next();
- /**
- * 如果当前时间-session的最后访问时间>1000*15(15秒)
- * session.getLastAccessedTime()获取session的最后访问时间
- */
- if(System.currentTimeMillis()-session.getLastAccessedTime()>1000*30){
- //手动销毁session
- session.invalidate();
- //移除集合中已经被销毁的session
- it.remove();
- }
- }
- }
- }
- }
javaWeb学习总结(11)- 监听器(Listener)在开发中的应用的更多相关文章
- JavaWeb学习 (二十七)————监听器(Listener)在开发中的应用
监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听 ...
- javaweb学习总结(四十七)——监听器(Listener)在开发中的应用
监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听 ...
- javaweb学习总结二十二(servlet开发中常见的问题汇总)
一:web应用的映射问题 通常我们从别人那里拷贝来的代码,自己会修改应用的名称,但是web映射的访问路径并没有修改,还是原来的映射. 解决方法: 工程右键--properties--myeclipse ...
- javaweb学习总结(四十三)——Filter高级开发
在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...
- JavaWeb学习笔记八 监听器
监听器Listener jservlet规范包括三个技术点:servlet :listener :filter:监听器就是监听某个对象的的状态变化的组件.监听器的相关概念事件源: 被监听的对象(三个域 ...
- ios学习笔记之block在ios开发中的应用
一.什么是Blocks Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从ios4.0开始就很好的支持Block. 二. ...
- JavaWeb学习总结第四篇--Servlet开发
Servlet开发 用户在浏览器中输入一个网址并回车,浏览器会向服务器发送一个HTTP请求.服务器端程序接受这个请求,并对请求进行处理,然后发送一个回应.浏览器收到回应,再把回应的内容显示出来.这种请 ...
- javaWeb学习之运用myeclipse结合tomcat开发一些简单的jsp和service
servlet是什么? servlet是java服务器端编程.不同于我们之前写的一般的java应用程序,Servlet程序是运行在服务器上的,服务器有很多种.....现在只是用过 tomcat ...
- JavaWeb学习记录(十九)——开发JSTL自定义标签
一.防盗链标签 import javax.servlet.http.HttpServletResponse;import javax.servlet.jsp.JspException;import j ...
随机推荐
- ajax第三步
ajaxSend()函数用于设置当AJAX请求即将被发送时执行的回调函数. 这是一个全局AJAX事件函数,用于为任何AJAX请求的ajaxSend事件绑定事件处理函数.当AJAX请求即将被发送时,将触 ...
- 重新认识JavaScript里的创建对象(一)
一.序 面向对象有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.ECMA-262把对象定义为"无序属性的集合,其属性可以包含基本值.对象或者函数&quo ...
- linux环境下安装jdk(本文示例是jdk1.6.0_export JAVA_HOME=/usr/java/jdk1.6.0_45 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar45)
第一步:创建一个文件夹安装jdk(虽说地址一般自定义,但是为了方便查找请按照笔者建议目录 ):/usr/java 将jdk-6u45-linux-x64.bin文件放到 /usr/java 文件夹 ...
- 在Centos中yum安装和卸载软件的使用方法
安装一个软件时 yum -y install httpd 安装多个相类似的软件时 yum -y install httpd* 安装多个非类似软件时 yum -y install httpd php p ...
- 记因PHP的内存溢出导致的事故之解决
如果对您有用记得关注,更多干货. 今天上午刚到公司,就有同事在公司群里反映某个计划任务出现问题了.我就怀着刨根问底的心,去查看了log.发现挺有意思的一个问题,PHP内存溢出导致脚本执行失败.那就一起 ...
- 第一章 自定义MVC框架
第一章 自定义MVC框架1.1 MVC模式设计 组成:Model:模型,用于数据和业务的处理 View :视图,用于数据的显示 Controller:控制器 ...
- 在Oracle中添加用户登录名称
第一步,打开Oracle客户端单击 “帮助”-->"支持信息"-->”TNS名“,加入红色部分.页面如下: 第二步,再次打开Oracle客户端时,就会显示数据库了,只需 ...
- css伪类的组合用法
利用伪类组合,可以用css代替js以达到目的,少些一下js .textarea:empty:before { display: block; content: '请输入'; color: #ababa ...
- File Transfer
本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师.何钦铭老师的<数据结构> 代码的测试工具PTA File Transfer 1 Question 2 Explain First, ...
- html字体问题
正如咱们在上一章中解说的那样,HTML元素使页面规划者能够对文档的构造进行符号.HTML标准列出了浏览器应该怎么显现这些元素的攻略.例如,您能够合理地保证强元素的内容将显现粗体.此外,您能够非常信赖大 ...