2011-05-23 31 views
1

更新:我用extraneon和Jarrod Roberson的答案混合使用。在Java中,如何運行differentes方法,每個線程中有一個?

我目前有四種方法,我想同時運行。他們是四個查詢數據庫。

我需要實現四個類,每個類都有一個run()與所需的查詢或有另一種方法來做到這一點?

編輯:這些方法將更新程序中的統計信息,並在名爲StatisticsDB的類中實現(下面的這些方法來自Facade因爲方法比這更大)。我有一個類將更新背景中的線程中運行的統計信息。我想要這樣的東西,可以是每個線程一個連接。

public void updateStatistics(){ 
    //these methods running at same time 
    pages = getQuantityVisitedPages(); 
    links = getQuantityFoundLinks(); 
    blinks = getQuantityBrokenLinks(); 
    flinks = getQuantityFilteredLinks(); 
} 

public String getQuantityVisitedPages(Connection conn) { 
    statisticsDB = new StatisticsDB(); 
    return statisticsDB.getQuantityVisitedPages(conn); 
} 

public String getQuantityFoundLinks(Connection conn) { 
    statisticsDB = new StatisticsDB(); 
    return statisticsDB.getQuantityFoundLinks(conn); 
} 

public String getQuantityBrokenLinks(Connection conn) { 
    statisticsDB = new StatisticsDB(); 
    return statisticsDB.getQuantityFilteredLinks(conn); 
} 

public String getQuantityFilteredLinks(Connection conn) { 
    statisticsDB = new StatisticsDB(); 
    return statisticsDB.getQuantityFilteredLinks(conn); 
} 
+0

這是一個Java程序? – 2011-05-23 19:47:17

+0

我忘了Java標籤。是的,這是一個Java程序。 – 2011-05-23 19:48:14

+0

你可以添加mote上下文嗎?誰會使用這些方法?它們是否相同,只有不同的連接? – 2011-05-23 19:52:43

回答

3

使用Future與贖回和ExecutorService的。

// Don't use the connection on all queries at the same time 
// unless that's allowed. 
Future<String> f1 = executor.submit(new Callable<String>() { 
    public String call() { 
     return getQuantityVisitedPages(createConnection()); 
    }}); 
Future<String> f2 = executor.submit(new Callable<String>() { 
    public String call() { 
     return getQuantityFoundLinks(createConnection()); 
    }}); 


try { 
    // wait until f1 is finished and get the result 
    // in the mean time all queries are running 
    String qvp = f1.get(); 
    String qfl = f2.get(); 
} catch (ExecutionException ex) { cleanup(); return; } 

// do something with found values 

編輯

只要是明確的 - 如果一個查詢失敗,你現在什麼都沒有。如果你可以忍受一個缺少的結果,那麼你只需在每一個get()中包裝try - catch。

一個get()阻止(雖然可選需要超時。所以f2.get()將立即返回,如果在平均時間的結果已經確定,否則它會等待直到F2也準備好了。

如果您想更新時,立即查詢完成後使更新可調用的圖形用戶界面部分的GUI,或在未來代替使用的SwingWorker

千萬要小心使用類的成員變量 - 併發訪問共享狀態可能會非常棘手,這就是爲什麼我提醒連接的原因,如果你使用連接池,請給每個呼叫建立一個自己的連接。

get()語義狀態表明發生異常時它將被包裝在ExecutionException中。只要得到原因()並確定應該做什麼。

至於一個合適的執行者,我認爲new Executors.newFixedThreadPool(4)將服務就好,或者如果你認爲更多的查詢將遵循,使用newCachedThreadPool。查詢對你的CPU來說並不是那麼緊密(它們是用於數據庫服務器的),所以一些額外的線程並不是真正的問題,因爲它們無論如何都在等待數據庫結果。

1

UPDATE:沒有注意到它與Java有關

但我會離開這裏的C#版本:

Task<string> task1 = Task.Factory.StartNew<string>(() => 
    { 
    return getQuantityVisitedPages(conn); 
    } 
Task<string> task2 = Task.Factory.StartNew<string>(() => 
    { 
    return getQuantityFoundLinks(conn); 
    } 
Task<string> task3 = Task.Factory.StartNew<string>(() => 
    { 
    return getQuantityBrokenLinks(conn); 
    } 
Task<string> task4 = Task.Factory.StartNew<string>(() => 
    { 
    return getQuantityFilteredLinks(conn); 
    } 
Task.WaitAll(task1, task2, task3, task4); 
Console.WriteLine(task1.Result); 
Console.WriteLine(task2.Result); 
Console.WriteLine(task3.Result); 
Console.WriteLine(task4.Result); 
+0

我相信這是C#? – extraneon 2011-05-23 19:53:11

+0

爲什麼所有的downvotes?這個問題始終沒有用語言標出。 – extraneon 2011-05-23 19:59:51

+0

是我的錯誤,我忘了把java標籤。 – 2011-05-24 02:39:06

3

要什麼從瞭解Futures和包。

這裏是你的代碼應該是什麼樣子的基本原理:

import java.sql.ResultSet; 
import java.util.concurrent.*; 

public class Main 
{ 
    public static void main(final String[] args) 
    { 
     final ExecutorService es = Executors.newFixedThreadPool(5); 
     final Future<ResultSet> rs1 = es.submit(new Query01()); 
     final Future<ResultSet> rs2 = es.submit(new Query02()); 
     final Future<ResultSet> rs3 = es.submit(new Query03()); 
     final Future<ResultSet> rs4 = es.submit(new Query04()); 

     // then you can test for completion with methods on 
     // rs1, rs2, rs3, rs4 and get the ResultSet with rs1.get(); 

     while (!f1.isDone() && !f2.isDone() && !f3.isDone() && !f4.isDone()) 
     { 
      // handle results that are complete 
     } 
    } 

    public static class Query01 implements Callable<ResultSet> 
    { 
     public ResultSet call() throws Exception 
     { 
      // Do work here and return ResultSet 
      return null; 
     } 
    } 
    public static class Query02 implements Callable<ResultSet> 
    { 
     public ResultSet call() throws Exception 
     { 
      // Do work here and return ResultSet 
      return null; 
     } 
    } 
     public static class Query03 implements Callable<ResultSet> 
    { 
     public ResultSet call() throws Exception 
     { 
      // Do work here and return ResultSet 
      return null; 
     } 
    } 
     public static class Query04 implements Callable<ResultSet> 
    { 
     public ResultSet call() throws Exception 
     { 
      // Do work here and return ResultSet 
      return null; 
     } 
    } 

} 
+0

我正在避免創建一個擴展Runnable或Calabble類,但似乎這是唯一的方法。 – 2011-05-24 12:15:17

相關問題