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

问题来自论坛,

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

 

其代码如下:

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") + "
" + "/n"); if (rs.getString("is_leaf").equals("N")) { tree(connection, rs.getInt("id"), level); } } } finally { Utils.slose(rs); Utils.close(ps); } } }

 

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

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

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

 

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

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") + "
" + "/n"); if (rs.getString("is_leaf").equals("N")) { tree(connection, rs.getInt("id"), level,sb); } } } finally { Utils.slose(rs); Utils.close(ps); } } }

你可能感兴趣的:(Java)