views:

208

answers:

2

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.

+1  A: 

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
Can you tell me with the above example how can i use Thread.join?
Rajesh Kumar J
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
@Rajesh: See e.g. http://www.jguru.com/faq/view.jsp?EID=15716 or http://www.jguru.com/faq/view.jsp?EID=15716
sleske
@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
+2  A: 

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

Joachim Sauer
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
@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