Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 455|回复: 0

[jsp学习]用jive的序列管理器做计数器

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-9-30 21:47:38 | 显示全部楼层 |阅读模式
    在制作站点计数器时,如果频繁的访问数数库(比如象哪种每增加一人,便写入数据库的作法),当你的站点有很大的访问量时,必然会影响性能。通常的做法有两种,一是启动一个线程定时写入访问量,二是先在内存中保存访问量,只有当访问量达到一定的数量(比如50人)时才写一次数据库。后者的做法更可取,我开始学习jsp时,不知道写计数器,看到jive中的序列管理器很合适“拿来”作计数器用,少许改动后便用它作了自己的第一个主页计数器(用会话session作为计数)。 后来看了一些开源代码,才了解了高手们是如何写计数器的。

      package test;
        import java.sql.*;
        public class SequenceManager {

        /**
        *记数增量,内存中访问量满50人时,才将数据写入数据库  
        */
         private static final int INCREMENT = 50;   
      

         /**
         *下一个访问量
         */
         public static long nextID() {
             return nextUniqueID();
         }

         /**
         *当前访问量
         */
         public static long currentID() {
             return oldid;
         }

         private static long currentID=0l;
         private static long oldid=0l;
         private static long maxID=0l;//当内存中的访问量大于此值时,更新数据库。

         /**
         * 创建一个新的序列管理器
         */
         public SequenceManager() {
         }

         /**
          * 返回下一个计数id.
          */
         public static synchronized long nextUniqueID() {
             if (currentID >= maxID) {
                 getNextBlock(5);//连5次数据库
             }
             oldid = currentID;
             currentID++;
             return oldid;
         }

         
         private static void getNextBlock(int count) {
               java.sql.Connection Conn=null;
               java.sql.Statement Stmt=null;
               java.sql.ResultSet Rst=null;
               if (count == 0) {
                 System.err.println("在最后一次尝试获取一个ID时失败, 异常中断...");
                 return;
               }
                 boolean success = false;
             
               try {
                 String con_string="jdbc:odbc:cwb";
                 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");  
                 Conn = DriverManager.getConnection(con_string);  
                 Stmt=Conn.createStatement();
                 String sqll="select * from count_num";
                 ResultSet rs=Stmt.executeQuery(sqll);
                      if (!rs.next()) {
                       throw new SQLException("Loading the current ID failed. The " +
                         "jiveID table may not be correctly populated.");
                      }
                 long currentID1 = rs.getLong(1);//取数据库中的访问量
                 long newID = currentID1 + INCREMENT;//访问量加50
                 sqll="update count_num set num="+newID;
                 if(currentID>=currentID1)    success=Stmt.executeUpdate(sqll)==1;
                 currentID = currentID1;
                 maxID = newID;
               }
               catch( Exception sqle ) {
                 sqle.printStackTrace();
                 }
               finally {
                 try {  Stmt.close();   }
                 catch (Exception e) { e.printStackTrace(); }
                 try {  Conn.close();   }
                 catch (Exception e) { e.printStackTrace(); }
               }
               if (!success) {
                 System.err.println("WARNING: failed to obtain next ID block due to " +
                     "thread contention. Trying again...");
                 // Call this method again, but sleep briefly to try to avoid thread
                 // contention.
                 try {
                     Thread.currentThread().sleep(75);
                 } catch (InterruptedException ie) { }
                 getNextBlock(count-1);//递归调用本方法
               }
          }
      }
       
    测试方法与代码:(在Tomcat 5下调试通过)
    先在Access中创建一数据库cwb,并创建表count_num,表中只有一个数字型字段num,并插入一条num为1的记录,jsp测试代码如下:
    test.jsp
    <%@ page contentType="text/HTML; charset=gb2312" %>
    <%@ page import="test.*"%>
        <%
         String login=(String)session.getAttribute("login");
         if(login==null){
        %>
             总访问量:<%=SequenceManager.nextID() %>  
        <%
          session.setAttribute("login","true");
         }else{
        %>
             总访问量:<%=SequenceManager.currentID() %>  
             <% } %>

      
      
       
       

         
       

       
       
      


    源码下载:http://file.javaxxz.com/2014/9/30/214738172.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-13 18:26 , Processed in 0.413334 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表