一个JAVA单例模式的典型错误应用的分析和解决方法

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

问题来自论坛,

http://topic.csdn.net/u/20090927/23/497372f4-af98-4b7b-8489-3eb3a8de43b5.html

 

其代码如下:

  1. import java.sql.Connection;  
  2. import java.sql.PreparedStatement;  
  3. import java.sql.ResultSet;  
  4. import java.sql.SQLException;  
  5. import com.cfd.drp.utils.Utils;  
  6. public class ClientManager {  
  7.   // 此处使用了实例级的属性  
  8.   StringBuffer sb = new StringBuffer();  
  9.   // 此处实现了单例模式  
  10.   private static ClientManager manager = new ClientManager();  
  11.   private ClientManager() {  
  12.   }  
  13.   public static ClientManager getInstance() {  
  14.     return manager;  
  15.   }  
  16.   // 这里没有同步,多个线程将同时调用这个方法  
  17.   public String showTree() {  
  18.     Connection connection = null;  
  19.     sb.delete(0, sb.length());  
  20.     try {  
  21.       connection = Utils.getConnection();  
  22.       tree(connection, 01);  
  23.     } catch (Exception e) {  
  24.       e.printStackTrace();  
  25.     } finally {  
  26.       Utils.close(connection);  
  27.     }  
  28.     return sb.toString();  
  29.   }  
  30.   public void tree(Connection connection, int id, int level) throws SQLException {  
  31.     String sql = "select * from t_client where pid = ?";  
  32.     int i = 0;  
  33.     PreparedStatement ps = null;  
  34.     ResultSet rs = null;  
  35.     try {  
  36.       ps = connection.prepareStatement(sql);  
  37.       ps.setInt(1, id);  
  38.       rs = ps.executeQuery();  
  39.       while (rs.next()) {  
  40.         sb.append(rs.getString("name") + "<br>" + "/n");  
  41.         if (rs.getString("is_leaf").equals("N")) {  
  42.           tree(connection, rs.getInt("id"), level);  
  43.         }  
  44.       }  
  45.     } finally {  
  46.       Utils.slose(rs);  
  47.       Utils.close(ps);  
  48.     }  
  49.   }  
  50. }  
import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import com.cfd.drp.utils.Utils;public class ClientManager {  // 此处使用了实例级的属性  StringBuffer sb = new StringBuffer();  // 此处实现了单例模式  private static ClientManager manager = new ClientManager();  private ClientManager() {  }  public static ClientManager getInstance() {    return manager;  }  // 这里没有同步,多个线程将同时调用这个方法  public String showTree() {    Connection connection = null;    sb.delete(0, sb.length());    try {      connection = Utils.getConnection();      tree(connection, 0, 1);    } catch (Exception e) {      e.printStackTrace();    } finally {      Utils.close(connection);    }    return sb.toString();  }  public void tree(Connection connection, int id, int level) throws SQLException {    String sql = "select * from t_client where pid = ?";    int i = 0;    PreparedStatement ps = null;    ResultSet rs = null;    try {      ps = connection.prepareStatement(sql);      ps.setInt(1, id);      rs = ps.executeQuery();      while (rs.next()) {        sb.append(rs.getString("name") + "<br>" + "/n");        if (rs.getString("is_leaf").equals("N")) {          tree(connection, rs.getInt("id"), level);        }      }    } finally {      Utils.slose(rs);      Utils.close(ps);    }  }}

 

具体的错误我已经在代码里标注出来了。

单例,就是系统只有一份实例,那么多个线程使用这一个实例,当然也就同时使用这一个StringBuffer了。

大家一起胡乱的往里面倾倒垃圾,怎么可能不混乱呢!

 

解决方法就是将StringBuffer做成局部变量

  1. import java.sql.Connection;  
  2. import java.sql.PreparedStatement;  
  3. import java.sql.ResultSet;  
  4. import java.sql.SQLException;  
  5. import com.cfd.drp.utils.Utils;  
  6. public class ClientManager {  
  7.   // 此处实现了单例模式  
  8.   private static ClientManager manager = new ClientManager();  
  9.   private ClientManager() {  
  10.   }  
  11.   public static ClientManager getInstance() {  
  12.     return manager;  
  13.   }  
  14.   // 这里没有同步,多个线程将同时调用这个方法  
  15.   public String showTree() {  
  16.     // 此处使用局部变量  
  17.     StringBuffer sb = new StringBuffer();  
  18.     Connection connection = null;  
  19.     try {  
  20.       connection = Utils.getConnection();  
  21.       tree(connection, 01, sb); // 作为参数调用  
  22.     } catch (Exception e) {  
  23.       e.printStackTrace();  
  24.     } finally {  
  25.       Utils.close(connection);  
  26.     }  
  27.     return sb.toString();  
  28.   }  
  29.   public void tree(Connection connection, int id, int level, StringBuffer sb) throws SQLException {  
  30.     String sql = "select * from t_client where pid = ?";  
  31.     int i = 0;  
  32.     PreparedStatement ps = null;  
  33.     ResultSet rs = null;  
  34.     try {  
  35.       ps = connection.prepareStatement(sql);  
  36.       ps.setInt(1, id);  
  37.       rs = ps.executeQuery();  
  38.       while (rs.next()) {  
  39.         sb.append(rs.getString("name") + "<br>" + "/n");  
  40.         if (rs.getString("is_leaf").equals("N")) {  
  41.           tree(connection, rs.getInt("id"), level,sb);  
  42.         }  
  43.       }  
  44.     } finally {  
  45.       Utils.slose(rs);  
  46.       Utils.close(ps);  
  47.     }  
  48.   }  
  49. }  
import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import com.cfd.drp.utils.Utils;public class ClientManager {  // 此处实现了单例模式  private static ClientManager manager = new ClientManager();  private ClientManager() {  }  public static ClientManager getInstance() {    return manager;  }  // 这里没有同步,多个线程将同时调用这个方法  public String showTree() {    // 此处使用局部变量    StringBuffer sb = new StringBuffer();    Connection connection = null;    try {      connection = Utils.getConnection();      tree(connection, 0, 1, sb); // 作为参数调用    } catch (Exception e) {      e.printStackTrace();    } finally {      Utils.close(connection);    }    return sb.toString();  }  public void tree(Connection connection, int id, int level, StringBuffer sb) throws SQLException {    String sql = "select * from t_client where pid = ?";    int i = 0;    PreparedStatement ps = null;    ResultSet rs = null;    try {      ps = connection.prepareStatement(sql);      ps.setInt(1, id);      rs = ps.executeQuery();      while (rs.next()) {        sb.append(rs.getString("name") + "<br>" + "/n");        if (rs.getString("is_leaf").equals("N")) {          tree(connection, rs.getInt("id"), level,sb);        }      }    } finally {      Utils.slose(rs);      Utils.close(ps);    }  }}

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值