2010-03-24 97 views
0

以下是我的課程代碼java的:所有的線程後關閉連接已經終止

import java.net.*; 
import java.util.*; 
import java.sql.*; 
import org.apache.log4j.*; 
class Database { 
    private Connection conn; 
    private org.apache.log4j.Logger log ; 
    private static Database dd=new Database(); 
    private Database(){ 
     try{ 
      log= Logger.getLogger(Database.class); 
      Class.forName("com.mysql.jdbc.Driver"); 
      conn=DriverManager.getConnection("jdbc:mysql://localhost/bc","root","root"); 
      conn.setReadOnly(false); 
      conn.setAutoCommit(false); 
      log.info("Datbase created"); 
      /*Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
      conn=DriverManager.getConnection("jdbc:odbc:rmldsn"); 
      conn.setReadOnly(false); 
      conn.setAutoCommit(false);*/ 

     } 
     catch(Exception e){ 
      log.info("Cant Create Connection"); 
     } 
    } 
    public static Database getDatabase(){ 
     return dd; 
    } 
    public Connection getConnection(){ 
     return conn; 
    } 
    @Override 
    protected void finalize()throws Throwable { 
     try{ 
     conn.close(); 
     Runtime.getRuntime().gc(); 
     log.info("Database Close"); 
     } 
     catch(Exception e){ 
      log.info("Cannot be closed Database"); 
     } 
     finally{ 
      super.finalize(); 
     }   
    } 
} 

這可只能通過getDatabase初始化數據庫對象()方法。下面是爲4個線程使用單個數據庫連接的程序。

public class Main extends Thread { 
    public static int c=0; 
    public static int start,end; 
    private int lstart,lend; 
    public static Connection conn; 
    public static Database dbase; 
    public Statement stmt,stmtEXE; public ResultSet rst; 
    /** 
    * @param args the command line arguments 
    */ 
    static{   
     dbase=Database.getDatabase(); 
     conn=dbase.getConnection(); 
    } 
    Main(String s){ 
     super(s); 
     try{ 
     stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
             ResultSet.CONCUR_UPDATABLE); 
     start=end; 
     lstart=start; 
     end=end+5; 
     lend=end; 
     System.out.println("Start -" +lstart +" End-"+lend); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void run(){ 
     try{ 

      URL url=new URL("http://localhost:8084/TestWeb/"); 


    rst=stmt.executeQuery("SELECT * FROM bc.cdr_calltimestamp limit "+lstart+","+lend); 

     while(rst.next()){ 

     try{ 
      rst.updateInt(2, 1); 
      rst.updateRow(); 
      conn.commit(); 
      HttpURLConnection httpconn=(HttpURLConnection) url.openConnection(); 
      httpconn.setDoInput(true); 
      httpconn.setDoOutput(true); 
      httpconn.setRequestProperty("Content-Type", "text/xml"); 
      //httpconn.connect(); 

      String reqstring="<?xml version=\"1.0\" encoding=\"US-ASCII\"?>"+ 
       "<message><sms type=\"mt\"><destination messageid=\"PS0\"><address><number" + 
       "type=\"international\">"+ rst.getString(1) +"</number></address></destination><source><address>" + 
       "<number type=\"unknown\"/></address></source><rsr type=\"success_failure\"/><ud" + 
       "type=\"text\">Hello World</ud></sms></message>"; 
      httpconn.getOutputStream().write(reqstring.getBytes(), 0, reqstring.length()); 

      byte b[]=new byte[httpconn.getInputStream().available()]; 
      //System.out.println(httpconn.getContentType()); 
      httpconn.getInputStream().read(b); 
      System.out.println(Thread.currentThread().getName()+new String(" Request"+rst.getString(1))); 
      //System.out.println(new String(b)); 
      httpconn.disconnect(); 
      Thread.sleep(100); 

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

     } 
      System.out.println(Thread.currentThread().getName()+" "+new java.util.Date()); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 

    } 

    public static void main(String[] args) throws Exception{ 
     System.out.println(new java.util.Date()); 
     System.out.println("Memory-before "+Runtime.getRuntime().freeMemory()); 
     Thread t1=new Main("T1-"); 
     Thread t2=new Main("T2-"); 
     Thread t3=new Main("T3-"); 
     Thread t4=new Main("T4-"); 
     t1.start(); 
     t2.start(); 
     t3.start(); 
     t4.start(); 

     System.out.println("Memory-after "+Runtime.getRuntime().freeMemory()); 


    } 

} 

我需要所有的線程被執行後,關閉連接。有沒有什麼好主意去做。請幫助我完成這項工作。

+0

http://stackoverflow.com/questions/2506488/java-finalize-method-call? – XpiritO 2010-03-24 09:48:12

+0

我改變了你的問題標題,因爲這個問題並不是最終確定的。 – sleske 2010-03-24 09:53:19

+1

旁註:永遠不要*處理這樣的例外。至少在異常處理程序中打印堆棧跟蹤。否則,錯誤不可能排除故障。我意識到這可能只是作業,但甚至不要開始習慣! – sleske 2010-03-24 09:57:12

回答

1

要在所有線程退出後關閉連接,您必須等待所有線程終止。

您可以使用Thread.join()等待一個線程。您必須爲每個線程執行此操作(一個接一個地執行)。此外,你必須趕上InterruptedException

+1

你能告訴我與上面的例子我怎麼能使用Thread.join? – 2010-03-24 10:20:01

+0

該解決方案實際上取決於「所有線程」的定義,除非使用Joachim提出的解決方案,否則執行的代碼仍將處於活動用戶(而不是VM)線程中。 – 2010-03-24 11:17:02

+0

@Rajesh:參見例如http://www.jguru.com/faq/view.jsp?EID=15716或http://www.jguru.com/faq/view.jsp?EID=15716 – sleske 2010-03-24 11:52:51

2

您可以使用Runtime.addShutdownHook()來註冊應該在JVM關閉之前運行的代碼。

+0

這可能是一個有問題的想法。引用API文檔:「關閉鉤子在虛擬機生命週期中的一個微妙時間運行,因此應該在防守方面進行編碼[...]」。它可能更安全(在不同的JVM上可移植),在退出main之前進行清理。另外,如果你以後將你的東西整合到一個更大的程序中,你不能再使用關閉鉤子了...... – sleske 2010-03-24 11:51:23

+1

@sleske:我大多同意,但正確使用關閉鉤子可能非常有用。此外,「退出主」並不一定意味着「結束程序」。 – 2010-03-24 12:06:23

相關問題