0

The following is my Class code

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();
        }        
    }
}

This can able to Initialize Database Object only through getDatabase() method. The below is the program which uses the single Database connection for the 4 threads.

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());


    }

}

I need to Close the connection after all the threads gets executed. Is there any good idea to do so. Kindly help me out in getting this work.

sleske
  • 81,358
  • 34
  • 189
  • 227
Rajesh Kumar J
  • 4,745
  • 6
  • 26
  • 25
  • http://stackoverflow.com/questions/2506488/java-finalize-method-call ? – XpiritO Mar 24 '10 at 09:48
  • I changed your question title, as the question is not really about finalization. – sleske Mar 24 '10 at 09:53
  • 1
    Sidenote: Please never, *ever* handle exceptions like this. At the very least print the stack trace in your exception handler. Otherwise errors are impossible to troubleshoot. I realize this is probably just homework, but don't even start the habit! – sleske Mar 24 '10 at 09:57

2 Answers2

2

You can use Runtime.addShutdownHook() to register code that should be run before the JVM shuts down.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • That's probably a problematic idea. To quote the API docs: "Shutdown hooks run at a delicate time in the life cycle of a virtual machine and should therefore be coded defensively.[...]". It is probably much safer (and portable across different JVMs) to just clean up before exiting main. Plus, if you later incorporate your stuff into a larger program, you cannot use shutdown hooks any longer... – sleske Mar 24 '10 at 11:51
  • 1
    @sleske: I mostly agree, but used correctly shutdown hooks can be very useful. Also, "exiting main" doesn't necessarily mean "ending the program". – Joachim Sauer Mar 24 '10 at 12:06
1

To close the connection after all threads have exited, you will have to wait for all threads to terminate.

You can use Thread.join() to wait for a thread. You'll have to do this for each thread (one after the other). ALso, you'll have to catch InterruptedException.

sleske
  • 81,358
  • 34
  • 189
  • 227
  • 1
    Can you tell me with the above example how can i use Thread.join? – Rajesh Kumar J Mar 24 '10 at 10:20
  • That solution really depends on the definition of "all threads", unless you use the solution proposed by Joachim, the code that executes will still be in a live user (as opposed to VM) thread. – M. Jessup Mar 24 '10 at 11:17
  • @Rajesh: See e.g. http://www.jguru.com/faq/view.jsp?EID=15716 or http://www.jguru.com/faq/view.jsp?EID=15716 – sleske Mar 24 '10 at 11:52
  • @M.Jessup: Yes, the cleanup will run in the regular main thread. Do you think that is a problem? And of course the program needs to know all its threads; after all it created them :-). – sleske Mar 24 '10 at 11:53