2014-01-17 47 views
1

比方說,例如,我有一個耗時的大型處理任務,通常需要查詢MySQL數據庫。我希望主線程在等待來自SQL服務器的響應時繼續處理,以便在另一個線程中進行查詢。從MySQL多線程獲得響應Java

如何獲取來自查詢的響應數據,如果它在另一個線程中?我可以將結果保存在數組或隊列中,但我不確定在單獨的線程中處理MySQL查詢時的最佳做法(使用連接池)。

謝謝。

回答

1

您可以使用另一個線程(或runnable)來獲取查詢結果,但要確保query-task是獨立的:它會打開一個連接(或從連接池獲取一個連接),觸發查詢,獲取結果,將結果存儲在某個變量(例如HashMap)中,關閉查詢,結果集和連接(或將其返回到池)。當所有這些完成後(使用適當的try-catch-finally塊),任務可以將數據「發送」到主處理線程。

使用在answer由TeresaCarrigan記載的方法,以下的例子如何一個「工作線程」可以「發送」數據的「主線程」:

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.BlockingQueue; 

public class Q21176667 implements Runnable { 

    private static volatile boolean stop; 

    public static void main(String... args) { 

     Thread t = new Thread(new Q21176667()); 
     t.start(); 
     sleep(200); 
     stop = true; 
    } 

    private BlockingQueue<Long> q = new ArrayBlockingQueue<Long>(100); 

    @Override 
    public void run() { 

     try { 
      while (!stop) { 
       if (q.peek() == null) { 
        new Thread(new GetUpdates(this)).start(); 
       } 
       long l = q.take(); 
       System.out.println("Main sleep: " + l); 
       sleep(l); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void add(Collection<Long> moreData) { 

     for (Long l : moreData) { 
      q.add(l); 
     } 
    } 

    static class GetUpdates implements Runnable { 

     final Q21176667 processor; 

     public GetUpdates(Q21176667 processor) { 
      this.processor = processor; 
     } 

     @Override 
     public void run() { 

      List<Long> vlist = new ArrayList<Long>(); 
      // Run query, process results 
      sleep(10); 
      Random r = new Random(); 
      for (int i = 0; i < 3; i++) { 
       vlist.add(new Long(r.nextInt(10))); 
      } 
      System.out.println("Adding " + vlist.size() + " more sleeps."); 
      processor.add(vlist); 
     } 
    } 

    public static void sleep(long timeMs) { 
     try { Thread.sleep(timeMs); } catch (Exception ignored) {} 
    } 

} 

輸出看起來像:

 
Adding 3 more sleeps. 
Main sleep: 5 
Main sleep: 9 
Main sleep: 0 
Adding 3 more sleeps. 
Main sleep: 3 
Main sleep: 7 
Main sleep: 8 
etc. 
0

一種方法是讓創建線程的類將「this」傳遞給運行線程的類的構造函數,並且當線程完成獲取結果時,它可以調用第一個類的公共方法將結果返回。如果這沒有足夠的意義,我可以提供代碼片段。