2011-05-23 26 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

相关问题