容器 删除操作 发生“并发修改异常”

转 http://even2012.iteye.com/blog/1963467


一般容器里面涉及到数据的添加移除操作,当出现多线程,就会出现并发修改异常,这个时候就可以加入锁机制


Servlet监听器应用案例—— 自定义session扫描器控制其主动销毁

 

Demo样例:SessionScanner.java

 

    public class SessionScanner implements HttpSessionListener,ServletContextListener { 

 

              private List list = Collections.synchronizedList(new LinkedList());

 

              private Object lock = new Object();

 

             

 

              // Web应用启动时,启动定时器!

 

              public void contextInitialized(ServletContextEvent sce) {    

 

                    Timer timer = new Timer();

 

                 

 

                    // 定时器任务:每隔30秒就扫描一次集合:是否有Session对象超时,若超时就会被处理(删除)

 

                    timer.schedule(new MyTask(list,lock), 0, 30*1000);

 

             }

 

     

 

          // Session创建的时候,就被添加到集合里面,进行控制管理

 

          public void sessionCreated(HttpSessionEvent se) {

 

                HttpSession session = se.getSession();

 

                System.out.println(session + "被创建了!!");

 

                synchronized (lock) {  //锁旗标——防止定时器中删除操作 发生“并发修改异常”。

 

                      list.add(session);

 

                }

 

          }

 

          public void sessionDestroyed(HttpSessionEvent se) {

 

                System.out.println(se.getSession() + "被销毁了");

 

          }

 

     

 

          public void contextDestroyed(ServletContextEvent sce) {

 

                // TODO Auto-generated method stub

 

          }

 

    }

 

 

 

    // 定时器任务

 

    class MyTask extends TimerTask{

 

     

 

          private List list;

 

          private Object lock; //接收锁旗标—— 防止定时器中删除操作 发生“并发修改异常”。

 

          public MyTask(List list,Object lock){

 

                this.list = list;

 

                this.lock = lock;

 

          }

 

     

 

      @Override

 

      public void run() {

 

            System.out.println("定时器执行!!");

 

            synchronized (this.lock) {

 

                  ListIterator it = list.listIterator();// 此处若使用Iterator,下面在删除操作时,就会发生“并发修改异常”。

 

                  while(it.hasNext()){

 

                        HttpSession session = (HttpSession) it.next();

 

                        if((System.currentTimeMillis()-session.getLastAccessedTime())>30*1000){

 

                              session.invalidate();

 

                              //list.remove(session);  //并发修改异常:ConcurrentModificationException

 

                              it.remove();

 

                        }

 

                  }

 

            }

 

      }

 

}


你可能感兴趣的:(java)