2012-02-13 11 views
0

データベース接続を処理するために独自の接続プールを使用しようとしていますが、スレッドを使用していても何らかの理由でブロックされているようですが、私の間違いを指摘してくれますか?スレッド付きJavaサーブレットがブロックされていますか?

スレッドクラスを持つサーブレットコードです。

protected void processRequest(HttpServletRequest request, 
     HttpServletResponse response) throws ServletException, IOException { 
    // PrintWriter out = response.getWriter(); 
    OutputStream ostream = response.getOutputStream(); 
    PrintStream out = new PrintStream(ostream, true, "UTF8"); 

    try { 

     response.setContentType("text/html"); 
     String test = request.getParameter("test"); 
     System.out.println("Received text: " + test); 

     if(test.equals("free")) 
     { 
      for (int i = 0; i < list.size(); i++) { 
       dbcm.freeConnection(list.get(i)); 
      } 
      list.clear(); 
     }else 
     { 
      GetConnThread gct = new GetConnThread(test, dbcm); 
      gct.start(); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
     out.println("fail"); 
    } finally { 
     out.close(); 
    } 

} 



private class GetConnThread extends Thread 
{ 
    private String test; 
    private DBConnectionManager dbcm; 

    public GetConnThread(String test, DBConnectionManager dbcm) 
    { 
     this.test = test; 
     this.dbcm = dbcm; 
    } 

    public void run() 
    { 
     try { 
      Connection conn = dbcm.getConnection(test); 
      list.add(conn);    
      System.out.println(conn); 
      System.out.println("list size: " + list.size()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 

これは私がサーブレットそれがこのコード行に行く3回目を呼び出した後、私は2に最大接続数を設定しDBConnectionManager

public synchronized Connection getConnection(String test) throws CGFatalException { 
     Connection con = null; 
     boolean connectionIsValid = false; 
     if (freeConnections.size() > 0) { 

      con = (Connection) freeConnections.firstElement(); 
      freeConnections.removeElementAt(0); 

      connectionIsValid = validateConnection(con); 
      if (connectionIsValid == false) { 
       con = getConnection(test); 
      } 
     } else if (maxConn == 0 || checkedOut < maxConn) { 
      con = newConnection(); 
      connectionIsValid = validateConnection(con); 
      if (connectionIsValid == false) { 
       con = getConnection(test); 
      } 
     }else 
     { 
      System.out.println("No available connections for " + test + ", try again in 2 secs...."); 
      try { 
       Thread.sleep(2000); 
       con = getConnection(test); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

     if (con != null && connectionIsValid == true) { 
      checkedOut++; 
     } 
     System.out.println("checkedOut: " + checkedOut); 
     System.out.println("maxConn: " + maxConn); 
     return con; 
    } 

でgetConnectionメソッドです:

System.out.println("No available connections for " + test + ", try again in 2 secs...."); 

私は4回目、それを呼び出すと、私は

System.out.println("No available connections for " + test + ", try again in 2 secs...."); 
を期待してい

別スレッドとして開始するが、3番目の呼び出しがブロックされているように見える場合は、接続をクリアするために「フリー」と呼び、すべてが正常に戻ってくることを期待していたため、無限ループが予想されます。

+0

私はあなたに詳細な情報を提供する必要があると思います。おそらくログファイルです。あなたは、無限ループが期待されていると言いますが、あなたは私たちに無限ループを示していません。 3番目の呼び出しがそれをブロックしているようですが、その証拠はないので、推測作業に頼らざるを得ません。 – Tim

+0

"無限ループ"は、再帰呼び出しがthread.sleep(2000)の後に "自由"な接続を試みることによって引き起こされます。 – Maurice

+1

純粋な趣味目的でない限り、スレッド化と同時実行性の仕組みが理解できない場合は** homegrow connection poolingをしないでください。既存の接続プールライブラリを選択します。すべての自尊心のあるservletcontainerには、Tomcatを含む接続プーリング機能が組み込まれています。それを利用する。本当に。接続プーリングは、健全なWebアプリケーションのあまりにも重要なアーティファクトであり、あなたは自信を持たずに理解することができます。 – BalusC

答えて

2

getConnectionメソッドが同期されています。他のすべてのスレッドは、「3番目の」要求が正常に接続されて処理されるまで、そのロック取得をブロックします。

+0

はいこれは正しいです。私はそれを削除してテストしました。私が "シンクロナイズド"キーワードを削除すると、あなたは見送りをしますか、私は結婚式に行くためのカウンターの面で直面するかもしれない大きな問題? – Maurice

+0

同期なしで壊れるように見える、はい。メソッド全体を同期させる代わりに、java.util.concurrent.locks.Lockを使用して、スリープ状態に入る前にロックを解除できるようにします。 – Affe

+0

ありがとうございます。新しいロック。 – Maurice

関連する問題