关于java线程释放资源问题

我于运行线程的时间出现这个错误
从一些资料上看到说是超过最大游标,需要修改代码
把循环改成外循环,可改成外循环的话,那我连接是无法获取数据库的数据

出现ORA-01000
java.sql.SQLException: ORA-01000: maximum open cursors exceeded

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oopen.receive(Oopen.java:120)
at oracle.jdbc.ttc7.TTC7Protocol.open(TTC7Protocol.java:611)
at oracle.jdbc.driver.OracleStatement.open(OracleStatement.java:575)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2803)
at oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:640)
at cn.soyu.sender.SendMailTest_G.sendMail(SendMailTest_G.java:107)
at cn.soyu.sender.SendMailTest_G.main(SendMailTest_G.java:269)

下面是我的代码,
请大家帮我看看
红字的部分资料说要改成外循环

代码
/*
* Created on 2004-12-28
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package cn.soyu.sender;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import cn.soyu.sender.comm.Email_Autherticatorbean;

/**
* @author singlebin
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class SendMailTest_G
{
public void sendMail(int year,int month)
{
System.out.println("Action start at:" + new Date().getTime());

String riqi1 = ""; //要查询的月份时间
if (month < 10)
{
riqi1 = riqi1.valueOf(year) + "0" + riqi1.valueOf(month);
}
else
{
riqi1 = riqi1.valueOf(year) + riqi1.valueOf(month);
}

String riqi2 = ""; //要查询的月份时间的下一个月的时间
if (month > 0 & month < 9)
{
riqi2 = riqi2.valueOf(year) + "0" + riqi2.valueOf(month + 1);
}
else if (month > 9 & month < 12)
{
riqi2 = riqi2.valueOf(year) + riqi2.valueOf(month + 1);
}
else
{
riqi2 = riqi2.valueOf(year + 1) + "0" + riqi2.valueOf(1);
}
try
{
//连接数据库,得到连接
Connection conn = null;
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn = DriverManager
.getConnection("jdbcracle:thin:@127.0.0.1:1521:billing",
"billing", "abcdef");
System.out.println("getConnection");
//按年月得到该月中使用过业务的每个用户的手机号
String sqlMobile = "select distinct acct_mobile_num from g_gd165_local where"
+ " charge_date > '" + riqi1 + "' and charge_date < '" + riqi2 + "'"
+ " and rownum<1000000000 "+" and acct_locate_code = 756 "
+" and acct_mobile_num>'13150000000' and acct_mobile_num<'13200000001'" ;
System.out.println("sqlMobile = " +"\n"+ sqlMobile);

Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sqlMobile);
//rs:手机号
while (rs.next())
{
String mobile = null;
mobile = rs.getString("acct_mobile_num");
//得到汇总
StringBuffer sqlBufAccount = new StringBuffer();
//输出汇总信息
StringBuffer account = new StringBuffer();
account
.append("用户:").append("\n")
.append(" 如下").append("\n")
.append(mobile).append("\n")
.append("---------------------------------------------------------------------------").append("\n")
.append("用户:").append(mobile).append(" 手机号码:").append(mobile)
.append(" 计费月份:").append(riqi1).append("\n");
//得到详单
StringBuffer sqlBufDetail = new StringBuffer();
sqlBufDetail.append("select rownum,oppose_number,")
.append("org_trm_id ,charge_date,charge_time,call_duration,")
.append("charge,").append("oppose_area_code from g_gd165_local_756 where charge_date > '")
.append(riqi1).append("'and charge_date < '").append(riqi2).append("' and acct_mobile_num ='")
.append(mobile).append("'").append(" and rownum<5000");
System.out.println("得到详单 = "+"\n"+sqlBufDetail.toString());
Connection con = null;
con = DriverManager
.getConnection("jdbcracle:thin:@127.0.0.1:1521:billing",
"billing", "abcdef");
Statement stm = conn.createStatement();
ResultSet rs3 = null;
rs3 = stm.executeQuery(sqlBufDetail.toString());
//显示详单信息
StringBuffer detail = new StringBuffer();
detail
.append("-------------------------------------------------------------------------------").append("\n")
.append(" NO. ").append(" ").append("对方号码 ").append(" ").append("类型 ").append(" ").append("日 期")
.append(" ").append("时 间").append(" ").append("时长(秒)").append(" ").append("话费(元) ").append(" ")
.append("通话地").append("\n")
.append("-------------------------------------------------------------------------------").append("\n");
while(rs3.next())
{
String org1=null;
if(rs3.getString("oppose_number")==null)
org1 = "0";
else
org1=rs3.getString("oppose_number");

detail
.append(StringUtil.padString(rs3.getString("rownum"),' ',3,StringUtil.LEFT))
.append(" ")
.append(StringUtil.padString(org1,' ',18,StringUtil.LEFT))
.append(" ")
.append(StringUtil.padString(org,' ',4,StringUtil.LEFT)).append("")
.append(" ")
.append(StringUtil.padString(rs3.getString("charge_date"),' ',8,StringUtil.LEFT))
.append(" ")
.append(StringUtil.padString(rs3.getString("charge_time"),' ',4,StringUtil.LEFT))
.append(" ")
.append(StringUtil.padString(String.valueOf(rs3.getInt("call_duration")),' ',4,StringUtil.LEFT))
.append("\t")
.append(StringUtil.padString(String.valueOf(rs3.getFloat("charge")),' ',4,StringUtil.LEFT))
.append("\t")
.append(StringUtil.padString(rs3.getString("oppose_area_code"),' ',4,StringUtil.LEFT))
.append("\n");
}
if(rs3 != null)
rs3 = null;
detail
.append("-------------------------------------------------------------------------------").append("\n") System.out.println("详单信息 = "+"\n"+detail.toString());
sendMain(account.toString()+detail.toString(),mobile+"@gd165.com");
}

下面这段代码有人说需要改成外循环
《《

if(rs!=null)
{
rs.close();
rs = null;
}
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (java.sql.SQLException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
》》
System.out.println("Action end at:" + new Date().getTime());
}

public static void sendMain(String content1, String to1)
{
//收件人
String to = null;
//发件人
String from = null;
//主题
String subject = null;
//抄送人
String cc = null;
//暗抄送
String bcc = null;
// mail 主机
String mailhost = null;
// mail 内容
String content = null;
//MIME邮件对象
MimeMessage mimeMsg = null;
//邮件会话对象
Session session = null;
//************ 不同之处 *************/
String user = null;
String password = null;
try
{
mailhost = "mail";
from = "singlebin@163.com";
to = to1;
subject = "";
content = content1;
//content = "这是个带身份验证的JavMail!"+"\n"+"This is a test";
user = "support";
password = "mail";

Properties props = System.getProperties(); //获得系统属性
props.put("mail.smtp.host", mailhost); //设置SMTP主机
props.put("mail.smtp.auth", "true"); //设置身份验证为真,若须身份验证则必须设为真

//获得邮件会话对象
//session = Session.getDefaultInstance(props,null);
//第二个参数为身份验证
session = Session
.getDefaultInstance(props, new Email_Autherticatorbean(user, password));

//创建MIME邮件对象
mimeMsg = new MimeMessage(session);
//设置发信人
mimeMsg.setFrom(new InternetAddress(from));

//设置收信人
if (to != null)
{
mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
}

//设置抄送人
if (cc != null)
{
mimeMsg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
}

//设置暗送人
if (bcc != null)
{
mimeMsg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc));
}

//设置邮件主题
mimeMsg.setSubject(subject, "GBK");

//设置邮件内容
mimeMsg.setText(content, "GBK");
//发送日期
mimeMsg.setSentDate(new Date());
//发送邮件
Transport.send(mimeMsg);
//System.out.println( "Email send!");

}
catch (Exception e)
{
e.printStackTrace();
}
}

public static void main(String[] args)
{
SendMailTest_G test = new SendMailTest_G();
test.sendMail(2004,11);
}
}




怎么没有人回答啊
我想了好多方法都感觉效果不好
关键是数据太大

我改了数据库的游标参数,效果也不好