2010-10-23 69 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