锁定老帖子 主题:一个常见的JDBC封装导致的问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (11) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-16
你这个单例写的,有可能产生死锁
|
|
返回顶楼 | |
发表时间:2011-05-16
sswh 写道 代码真够混乱的。 本来不想回了,算了,还是说一下吧。 悲剧了 写道 public class ConnectionUtil { private static Connection instance=null; } 这儿:instance是ConnectionUtil 类的静态变量。 悲剧了 写道 public static void close(Connection con){ if(con!=null){ try { con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ con=null; } } } } 这儿:close()方法中,置空的con=null,是方法参数。ConnectionUtil.instance 并没有受到影响。 正解,Java的参数都是值传递,非引用传递 |
|
返回顶楼 | |
发表时间:2011-05-16
悲剧了 写道 大家看一个数据库封装类
操作一次没问题,操作两次就报错 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. Debug调试,发现connection不能真正关掉,使用connection完后,调用close()方法,下次getConnection()时候 instance不为null public class ConnectionUtil { private final static String url="jdbc:mysql://localhost:3306/qq?useUnicode=true&characterEncoding=UTF-8"; private final static String username="root"; private final static String password="root"; private static Connection instance=null; private ConnectionUtil(){ if(instance==null){ try { Class.forName("org.gjt.mm.mysql.Driver"); instance=DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } public static Connection getConnection(){ if(instance==null){ new ConnectionUtil(); } return instance; } public static void close(Connection con,PreparedStatement ps,ResultSet rs){ if(con!=null){ try { con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ con=null; } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ ps=null; } } if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ rs=null; } } } public static void close(Connection con,PreparedStatement ps){ if(con!=null){ try { con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ con=null; } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ ps=null; } } } public static void close(Connection con){ if(con!=null){ try { con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ con=null; } } } } 一个connetion.close掉了就不可以用了,你这里if(instance==null),第二次用的时候install不为null,是一个connection对象,但他的状态时closed,所以下面的if语句块,不会执行。今天没认真看代码,罪过,罪过... 结贴了。。。。有其他结贴方式吗? |
|
返回顶楼 | |
发表时间:2011-05-16
非常常用的功能,建议先找找有没通用的开源实现
http://commons.apache.org/dbutils/ |
|
返回顶楼 | |
发表时间:2011-05-17
悲剧了 写道 gaosheng08 写道 close()中还要加一句instance = null;
调用的时候传进来的就是instance ,这个connection是通过这个类的getConnection()得到的 instance 和 con 是一个对象的两个引用,假设对象为A, B和C为到A的引用,C=null只是切断了C到A的联系,B与A的联系依然存在。 |
|
返回顶楼 | |
发表时间:2011-05-17
ecokozhangtao 写道 你这个单例写的,有可能产生死锁
连同步都没有,还能出来死锁.... |
|
返回顶楼 | |
发表时间:2011-05-17
最后修改:2011-05-17
悲剧了 写道 kakaluyi 写道 悲剧了 写道 gaosheng08 写道 close()中还要加一句instance = null;
调用的时候传进来的就是instance ,这个connection是通过这个类的getConnection()得到的 lz你难道不知道java通过close方法传递进去的instance只是个引用吗,真正的instance是不会置为null的?? 哥们我明白了 con,intance 两个引用指向同一个栈,con为空但intance不为空,开始是以为传进去的是intance Connection con=instance con=null 但intance不为空 哎,悲剧,估计又要挨骂了 +1 new ConnectionUtil 匿名对象 |
|
返回顶楼 | |
发表时间:2011-05-17
没发现搂主 instance=null 的语句
|
|
返回顶楼 | |
发表时间:2011-05-17
这个单列写的。。。。。。。我看着似乎不敢发言了。
|
|
返回顶楼 | |
发表时间:2011-05-18
最后修改:2011-05-18
kakaluyi 写道 算了解释一下,发现楼主还是云里雾里
public void static main(String args[]) { int i=3; changevalue(i); System.out.println(i); //你以为i现在是2吧,错了,i还是3!不好意思楼主,你理解错误了。这个是很容易搞错的概念 } public void changevalue(int i) { i=2; } 朋友很热心,但是你却没有明白Java的基本数据类型与引用类型的区别。 你这样会对人造成误导的,不是楼主搞错了而是你搞错了。 楼主的代码写得确实很混乱。 |
|
返回顶楼 | |