问题描述
先来看我的线程 private DataHandle dh = new DataHandle(); public synchronized void runTask() { try { dh.handle(pbean.getStartNo(), pbean.getEndNo()); } catch (Exception e) { e.printStackTrace(); // TaskManagerBean.returnItem(); } 这个是我的线程,里面用到一个叫DataHandle的类,现在来看这个DataHandle的类 public synchronized void handle(String start, String end) { Statement stmt = null; ResultSet rs = null; StringBuffer sb = new StringBuffer(); try { if (conn != null) { sb.append("select tid,tname,description,dbvalue,xmlvalue"); sb.append(" from exporttable limit " + start + "," + end); System.out.println("sql===" + sb.toString()); stmt = conn.createStatement(); rs = stmt.executeQuery(sb.toString()); while (rs.next()) { db = new DataBean(); db.setTname(StringUtil.replaceNull(rs .getString("tname"))); db.setDescription(StringUtil.replaceNull(rs .getString("description"))); db.setDbValue(StringUtil.replaceNull(rs .getString("dbvalue"))); db.setXmlValue(StringUtil.replaceNull(rs .getString("xmlvalue"))); /* resultList.add(db); */ // dealing(db); } /* return resultList; */ } } catch (Exception e) { e.printStackTrace(); } finally { try { rs.close(); rs = null; } catch (Exception e) { } try { stmt.close(); stmt = null; } catch (Exception e) { } try { conn.close(); conn = null; } catch (Exception e) { } } } 这个类里有一个handle方法 这个线程是这样运行的,5个线程 第一个线程取0-100条记录 第二个线程取100-200条记录 第三个线程取200-300条记录 . . . 依此类推, 现在的问题时,程序在运行时经常出现:resultset have been closed这样的问题 经分析,是因为5个线程中,每个线程都有操作DataHandle的类,那么内存中就有5个DataHandle类,每个类中由于都进行resultset的打开,因此在运行时, 会发生一个线程中的ResultSet还在被操作时,已经被另一个线程中的ResultSet关闭的情况 我试过了 在DataHandle中Synchronized(rs),synchronized(stmt),甚至我的方法大家都看到了,都是synchronized的,为什么还会发生这样的事,大家有没有好的解决方法 多说一句,每个DataHandle中打开一个connection即每个线程都开一个单独的CONNECTION的,然后操作完100条数据后关闭,因此始终是存在5个线程,5个connection,5个resultset. 还是我的设计上有问题,我的设计就想是 多个线程,同时读数据库,只不过是每个线程读不同的数据块,就像我前面提到过的一样,0-100,100-200这样读的. 问题补充:我的CONNECTION是在JBOSS里设了一个数据库连接池,然后我这个是应用程序在应用程序里我是如此得到的:public class JndiContext {private static JndiContext m_instance = null;public static DataSource ds = null;private JndiContext() {}synchronized public static JndiContext getInstance() {if (m_instance == null) {try{Properties props = new Properties();props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");props.setProperty("java.naming.provider.url", "localhost:9099");Context ctx = new InitialContext(props);ds = (DataSource) ctx.lookup("MySqlDS");}catch(Exception e){ds = null;e.printStackTrace();}m_instance = new JndiContext();}return m_instance;}}然后我有一个DataConnection类类里是这样得到CONNECTION的Connection getDataConnection(){Connection conn = null;try{conn = JndiContext.getInstance().ds.getConnection();return conn;}catch(Exception e){e.printStackTrace();return null;}}
解决方案
估計conn不是独立的,可能你把conn.close(); 放到DataHandle 類以外操作可能handle方法就不會出現這個錯誤了,但是具體原因還是要知道conn是怎么生成的?
解决方案二:
你的5个线程产生的代码段贴出来分析下。
解决方案三:
建议把完整的代码贴出来!如果真正是每个线程里面各有1套独立的 connection/statement,resultset,应该不会出现“resultset have been closed”问题。