查看: 899|回复: 0

[JavaSE] [参赛]用jive的序列管理器做计数器

[复制链接]
  • TA的每日心情
    开心
    2017-5-15 11:40
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    发表于 2014-6-18 15:37:01 | 显示全部楼层 |阅读模式
    1. 在制作站点计数器时,如果频繁的访问数数库(比如象哪种每增加一人,便写入数据库的作法),当你的站点有很大的访问量时,必然会影响性能。通常的做法有两种,一是启动一个线程定时写入访问量,二是先在内存中保存访问量,只有当访问量达到一定的数量(比如50人)时才写一次数据库。后者的做法更可取。
    复制代码
    1. package test;
    2.     import java.sql.*;
    3.     public class SequenceManager {

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


    8.      /**
    9.      *下一个访问量
    10.     */
    11.      public static long nextID() {
    12.          return nextUniqueID();
    13.      }

    14.      /**
    15.      *当前访问量
    16.     */
    17.      public static long currentID() {
    18.          return oldid;
    19.      }

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

    23.     /**
    24.      * 创建一个新的序列管理器
    25.     */
    26.      public SequenceManager() {
    27.      }

    28.      /**
    29.       * 返回下一个计数id.
    30.       */
    31.      public static synchronized long nextUniqueID() {
    32.          if (currentID >= maxID) {
    33.              getNextBlock(5);//连5次数据库
    34.         }
    35.          oldid = currentID;
    36.          currentID++;
    37.          return oldid;
    38.      }

    39.      
    40.      private static void getNextBlock(int count) {
    41.            java.sql.Connection Conn=null;
    42.            java.sql.Statement Stmt=null;
    43.            java.sql.ResultSet Rst=null;
    44.            if (count == 0) {
    45.              System.err.println("在最后一次尝试获取一个ID时失败, 异常中断...");
    46.              return;
    47.            }
    48.              boolean success = false;
    49.          
    50.            try {
    51.              String con_string="jdbc:odbc:cwb";
    52.              Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");  
    53.              Conn = DriverManager.getConnection(con_string);  
    54.              Stmt=Conn.createStatement();
    55.              String sqll="select * from count_num";
    56.              ResultSet rs=Stmt.executeQuery(sqll);
    57.                   if (!rs.next()) {
    58.                    throw new SQLException("Loading the current ID failed. The " +
    59.                      "jiveID table may not be correctly populated.");
    60.                   }
    61.              long currentID1 = rs.getLong(1);//取数据库中的访问量
    62.             long newID = currentID1 + INCREMENT;//访问量加50
    63.              sqll="update count_num set num="+newID;
    64.              if(currentID>=currentID1)    success=Stmt.executeUpdate(sqll)==1;
    65.              currentID = currentID1;
    66.              maxID = newID;
    67.            }
    68.            catch( Exception sqle ) {
    69.              sqle.printStackTrace();
    70.              }
    71.            finally {
    72.              try {  Stmt.close();   }
    73.              catch (Exception e) { e.printStackTrace(); }
    74.              try {  Conn.close();   }
    75.              catch (Exception e) { e.printStackTrace(); }
    76.            }
    77.            if (!success) {
    78.              System.err.println("WARNING: failed to obtain next ID block due to " +
    79.                  "thread contention. Trying again...");
    80.              // Call this method again, but sleep briefly to try to avoid thread
    81.              // contention.
    82.              try {
    83.                  Thread.currentThread().sleep(75);
    84.              } catch (InterruptedException ie) { }
    85.              getNextBlock(count-1);//递归调用本方法
    86.           }
    87.       }
    88.   }
    89.    
    90. 测试方法与代码:(在Tomcat 5下调试通过)
    91. 先在Access中创建一数据库cwb,并创建表count_num,表中只有一个数字型字段num,并插入一条num为1的记录,jsp测试代码如下:
    92. test.jsp
    93. <%@ page contentType="text/html; charset=gb2312" %>
    94. <%@ page import="test.*"%>
    95.     <%
    96.      String login=(String)session.getAttribute("login");
    97.      if(login==null){
    98.     %>
    99.          总访问量:<%=SequenceManager.nextID() %>  
    100.     <%
    101.       session.setAttribute("login","true");
    102.      }else{
    103.     %>
    104.          总访问量:<%=SequenceManager.currentID() %>  
    105.          <% } %>
    复制代码


    您需要登录后才可以回帖 登录 | 注册青鸟豆号

    本版积分规则

    Copyright 1999-2019 Beijing Aptech Beida Jade Bird Information Technology Co.,Ltd

    北大青鸟IT教育 北京阿博泰克北大青鸟信息技术有限公司 版权所有

    京ICP备11045574号-3 京公网安备11010802013845号

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