2014-05-15 2 views
0

SQL 데이터베이스 (hsqldb)가 있고 내용을 수정하지 않는 여러 쿼리를 실행하려고한다고 가정 해 보겠습니다. 일부 쿼리에는 시간이 오래 걸리고 여러 스레드에서 쿼리를 실행하고 싶습니다. 내 질문은 : 이것을 구현하는 가장 좋은 방법은 무엇입니까?여러 스레드에서 SQL 쿼리 실행 (HSQLDB)

나는 이것을하기위한 좋은 샘플을 찾지 못했고, 다음과 같은 것을 생각해 냈다.

첫 번째로 매우 간략하게 말하면 다음과 같습니다. 쿼리에 액세스하고 결과를 저장하기 위해 thread-safe 컬렉션을 사용합니다. 쿼리는 여러 작업자 스레드에서 실행됩니다. 결과는 모든 스레드가 완료 될 때까지 새로운 결과를 검사하는 주 스레드에서 처리됩니다.

지금 코드 :

쿼리 및 결과 스레드 안전 컬렉션을 만듭니다

ConcurrentLinkedQueue<String> queries = new ConcurrentLinkedQueue<String>() 
ConcurrentLinkedQueue<ResultSet> sqlResults = new ConcurrentLinkedQueue<ResultSet>(); 

스레드의 수를 생성하고 시작 (편집) 다음 내

ExecutorService executorService = Executors.newFixedThreadPool(4); 
for(int i=0; i<4; i++){ 
    executorService.execute(new QueryThread(sqlResults, queries)); 
} 

스레드 클래스 QueryThread 왼쪽에있는 한 연결이 열리고 쿼리가 실행됩니다.

private class QueryThread implements Runnable { 
    private ConcurrentLinkedQueue<ResultSet> sqlResults; 
    private ConcurrentLinkedQueue<String> queries; 

    public QueryThread(ConcurrentLinkedQueue<ResultSet> sqlResults, ConcurrentLinkedQueue<String> queries){ 
     this.sqlResults = sqlResults; 
     this.queries = queries; 
    } 

    @Override 
    public void run(){ 
     Connection connThr = null; 
     try{ 
      try { 
       connThr = DriverManager.getConnection(dbModeSave, "sa", ""); 
       connThr.setAutoCommit(false); 
      } catch (SQLException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 

      String currentQuery; 
      do { 
       currentQuery = queries.poll(); // get and remove element from remaining queries 
       if (currentQuery != null) { // only continue if element was found 
        try { 
         Statement stmnt = connThr.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); 
         try { 
          ResultSet resultSet = stmnt.executeQuery(currentQuery); 
          sqlResults.add(resultSet); 
         } catch (SQLException e) { 
          // (Do something specific) 
         } finally { 
          stmnt.close(); 
         } 
        } catch (SQLException e) { 
         // (Do something specific) 
        } 
       } 
      } while (currentQuery != null); 

     } finally { 
      if (connThr != null) { 
       try { 
        connThr.close(); 
       } catch (SQLException e) { 
        // Nothing we can do? 
       } 
      } 
     } 
    } 
} 

스레드가 모두 완료되어 모든 쿼리가 처리 (편집) 된 경우 원래 스레드에서 확인합니다.

while (!executorService.isTerminated()) { 
    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } 
    while (!sqlResults.isEmpty()) { 
     ResultSet result = sqlResults.poll(); 
     //process result and close it in the end 
    } 
} 

답변

0

병렬 처리를위한 Java 표준 코드는 ThreadPoolExecutor입니다. 시도 해봐.

+0

좋아, 그래서 스레드 생성을 ThreadPoolExecutor로 변경했습니다. 고마워요. 하지만 내가 관심있는 부분은 ConcurrentLinkedQueue와 SQL 연산의 사용이다. – user3541377