2010-03-24 5 views
0

다음 종료 된 것은 내 클래스 코드자바 : 모든 스레드 후 닫기 연결이

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

+0

질문이 마무리에 관한 것이 아니기 때문에 질문 제목이 변경되었습니다. – sleske

+1

Sidenote : 절대로 이런 예외를 처리하지 마십시오. 적어도 예외 처리기에서 스택 추적을 인쇄하십시오. 그렇지 않으면 오류를 해결하는 것이 불가능합니다. 나는 이것이 아마도 숙제 일뿐만 아니라 습관을 시작하지도 않는다는 것을 깨닫는다! – sleske

답변

1

모든 스레드가 종료 된 후 연결을 닫으려면 모든 스레드가 종료 될 때까지 기다려야합니다.

Thread.join()을 사용하면 스레드를 기다릴 수 있습니다. 각 스레드 (하나씩 차례로)마다이 작업을 수행해야합니다. 또한 InterruptedException을 잡아야합니다.

+1

위 예제에서 Thread.join을 어떻게 사용할 수 있습니까? –

+0

그 솔루션은 실제로 "모든 스레드"의 정의에 의존합니다. Joachim이 제안한 솔루션을 사용하지 않는 한 실행되는 코드는 실제 사용자 (VM과 반대되는 스레드)에 남아 있습니다. –

+0

@Rajesh : 예를 들어 http://www.jguru.com/faq/view.jsp?EID=15716 또는 http://www.jguru.com/faq/view.jsp?EID=15716 – sleske

2

을 사용하면 JVM이 종료되기 전에 실행해야하는 코드를 등록 할 수 있습니다.

+0

아마도 문제가되는 아이디어 일 겁니다. API 문서를 인용하면 다음과 같이 나타납니다. "셧다운 훅은 가상 머신의 라이프 사이클에서 섬세한 시간에 실행되므로 방어 적으로 코딩되어야합니다. [...]". main을 종료하기 전에 정리하는 것이 훨씬 안전합니다 (다른 JVM에서 이식 할 수 있습니다). 또한, 나중에 더 큰 프로그램에 물건을 통합하면 더 이상 종료 후크를 사용할 수 없습니다. – sleske

+1

@sleske : 대부분 동의하지만 제대로 종료 걸이를 사용하면 매우 유용 할 수 있습니다. 또한, "exiting main"은 반드시 "프로그램 종료"를 의미하지는 않습니다. –

관련 문제