2011-08-19 20 views
1

ここには私が実装したConnectionPoolがあります。すべての変数とメソッドを静的にするのは良い設計ですか?それはなぜ接続プールJava

public class MyCp1 { 

    private static final int MAX_SIZE=100; 
    private static final BlockingQueue<Connection> bq; 

    static{ 
     System.out.println("Inside begin static block"); 
     bq= new ArrayBlockingQueue<Connection>(MAX_SIZE); 
     for(int i=0;i<MAX_SIZE;i++) 
     { 
      try { 
       try { 
        bq.put(makeConnection()); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } catch (SQLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     System.out.println("total size:" + bq.size()); 
    } 

    public static Connection getConnection() throws InterruptedException 
    { 
     System.out.println("size before getting connection "+ bq.size()+ " Thread name "+ Thread.currentThread().getName()); 
     Connection con=bq.take(); 
     System.out.println("size after getting connection "+ bq.size()+" Thread name "+ Thread.currentThread().getName()); 
     return (con); 
    } 

    public static boolean releaseConnection(Connection con) throws InterruptedException 
    { 
     System.out.println("size before releasing connection "+ bq.size()+" Thread name "+ Thread.currentThread().getName()); 
     boolean bool =bq.add(con); 
     System.out.println("size after releasing connection "+ bq.size()+" Thread name "+ Thread.currentThread().getName()); 
     return (bool); 
    } 

    public static Connection makeConnection() throws SQLException { 
     Connection conn = null; 
     Properties connectionProps = new Properties(); 
     connectionProps.put("user", "root"); 
     connectionProps.put("password", "java33"); 
     try { 
      Class.forName("com.mysql.jdbc.Driver"); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     conn = DriverManager.getConnection("jdbc:" + "mysql" + "://" 
       + "localhost" + ":" + "3306" + "/test", connectionProps); 

     System.out.println("Connected to database"); 
     return conn; 
    } 


} 

私は例外処理などに問題がある知っているが、あなたは上記の質問

EDITに固執してくださいすることができます場合、私は感謝教えてください::

それは、静的を使用するように見えるが好まれていない。だから私は静的を取り除くためにできる限りリファクタリングしました。これが機能している間、これが良いデザインであるかどうかは分かりません

public class ConnectionPool { 

    private static final int MAX_SIZE = 100; 
    private BlockingQueue<Connection> bq; 
    private static ConnectionPool cp= new ConnectionPool(); 


    private ConnectionPool(){ 
     System.out.println("inside constructor"); 
     bq = new ArrayBlockingQueue<Connection>(MAX_SIZE); 
     Properties connectionProps = new Properties(); 
     connectionProps.put("user", "root"); 
     connectionProps.put("password", "java33"); 
     try { 
      Class.forName("com.mysql.jdbc.Driver"); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     for (int i = 0; i < MAX_SIZE; i++) { 
      try { 
       bq.put(makeConnection(connectionProps)); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (SQLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 

     System.out.println("total size:" + bq.size()); 
    } 
    public static ConnectionPool getInstance() 
    { 
     return cp; 

    } 

    public Connection getConnection() throws InterruptedException { 
     System.out.println("size before getting connection" + bq.size()); 
     Connection con = bq.take(); 
     System.out.println("size after getting connection" + bq.size()); 
     return (con); 
    } 

    public void releaseConnection(Connection con) 
      throws InterruptedException { 
     System.out.println("size before releasing connection" + bq.size()); 
     bq.put(con); 
     System.out.println("size after releasing connection" + bq.size()); 
     //return (bool); 
    } 

    private Connection makeConnection(Properties connectionProps) throws SQLException { 
     Connection conn = null; 
     conn = DriverManager.getConnection("jdbc:" + "mysql" + "://" 
       + "localhost" + ":" + "3306" + "/test", connectionProps); 

     System.out.println("Connected to database"); 
     return conn; 
    } 

} 
+4

接続プールの実装を記述する必要はありません。 [DBCP](http://commons.apache.org/dbcp/)または[C3P0](http://sourceforge.net/projects/c3p0/)を使用してください。なぜホイールを再発明するのですか? :) – CoolBeans

+3

[BoneCP](http://jolbox.com)。 Javaに慣れていなくても、 'static'をいつ使うのかはすでに分かっていない限り、接続プールなどの非常に重要なソフトウェア面を再考しようとしないでください。遅かれ早かれあなたを殺します。 – BalusC

+0

練習ですか? 'commons-dbcp'または' c3p0'オープンソースプールを使うことをお勧めします。 –

答えて

2

絶対にありません。あなたが持っているものは、オブジェクトリサイクラのものです。それが必要なものであれば問題ありません。接続プールの

(リサイクル業者として、しかし、あなたはまだ、静的フィールドを望んでいないが、あなただけのリサイクル業者の1つのインスタンスを作成すると思います。)

(およびJDBC接続のようなもののために、この場合)スレッドセーフである必要があり、理想的には接続を返す必要はありません。

スレッドセーフである接続プールは、ThreadLocalを使用して、そのスレッドでのみ使用される接続を返します。利用できない場合は、ThreadLocal.initialValue()を実装して新しい接続を作成します。

また、スレッドはExecutorServiceを使用して作成する必要があります)ので、スレッドも再利用します。

+2

プールをスレッドセーフにする方法はたくさんあります。スレッドへの接続を捧げることは、多くの中の1つに過ぎず、これが最良のアプローチであろうと良いアプローチであろうとも、状況によって異なります。 – erickson

+1

'Executors.newCachedThreadPool'を使用すると、未使用のスレッドが60秒のタイムアウト後に死んでしまうような場合は、あなたのアプローチではあまり*プーリング*しません。 –