2010-10-23 2 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 и дать ему FutureTask.

Вы можете дождаться результатов, вызвав блокировку get() в возвращаемом Будущем. Сканирование будет выполняться параллельно, но ваш метод запуска (показанный здесь) будет по-прежнему ждать завершения сканирования.

Немного напоминает:

 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

ТНАК вы: Я сделал это так http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/ Chapter10/concurrencyTools.html – vale4674

+0

@ vale4674 Если вы решили поиграть с потоками и начать делиться данными между потоками _between_, я настоятельно рекомендую http://www.javaconcurrencyinpractice.com/ (книга). Использование потоков может иметь странные результаты, когда вы не будете осторожны. Конечно, это не проблема. – extraneon