2010-10-23 62 views
3

我已经有做以下工作一个线程:Java的异步方法调用

public class DetectionHandler extends TimerTask { 

@Override 
public void run() { 
bluetoothAddresses = BluetoothModule.scanAddresses(); 
wiFiAddresses = WiFiModule.scanAddresses(); 
...//when scanning is finished, continue work 
} 

我想是扫描平行。所以我认为我必须异步调用这两种方法。当扫描完成后,我可以继续在DetectionHandler类中工作。

我试过BluetoothModule和WiFiModule实现Runnable的方式,但没有运气。 Tnx

回答

4

使用ExecutorService你可以写这样的事情:

ArrayList<Callable<Collection<Address>>> tasks = new ArrayList<Callable<Collection<Address>>>(); 
tasks.add(new Callable<Collection<Address>>() { 
    public Collection<Address> call() throws Exception { 
    return BluetoothModule.scanAddresses(); 
    } 
}); 
tasks.add(new Callable<Collection<Address>>() { 
    public Collection<Address> call() throws Exception { 
    return WiFiModule.scanAddresses(); 
    } 
}); 

ExecutorService executorService = Executors.newFixedThreadPool(2); 
List<Future<Collection<Address>>> futures = executorService.invokeAll(tasks); 
3

Executors获取一个ExecutorService并给它一个FutureTask

然后,您可以通过调用返回的Future上的阻止get()来等待结果。扫描将平行运行,但您的运行方法(此处显示)仍将等待扫描完成。

如A位:

 FutureTask<List<Address>> btFuture = 
     new FutureTask<List<Address>>(new Callable<List<Address>>() { 
     public List<Address> call() { 
      return BluetoothModule.scanAddresses(); 
     }}); 
    executor.execute(btFuture); 

    FutureTask<List<Address>> wfFuture = 
     new FutureTask<List<Address>>(new Callable<List<Address>>() { 
     public List<Address> call() { 
      return WifiModule.scanAddresses(); 
     }}); 
    executor.execute(wfFuture); 

    btAddresses = btFuture.get(); // blocks until process finished 
    wifiAddresses = wfFuture.get(); // blocks 

要当心不过,得到的将返回任何调用返回。异常包装在ExecutionException中。

+1

tnak你:我做了这样的http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/ Chapter10/concurrencyTools.html – vale4674 2010-10-23 16:41:14

+0

@ vale4674如果你决定玩线程并开始在线程间共享数据,我衷心推荐http://www.javaconcurrencyinpractice.com/(该书)。不小心使用线程可能会产生奇怪的结果。当然这不是一个问题。 – extraneon 2010-10-23 20:28:58