2012-11-12 63 views
2

裏面我有這個簡單的問題:激活鎖定一個正在運行的線程的Android

在服務我需要運行2個相互獨立的線程,我需要一個喚醒鎖定,讓他們執行。我給你舉個例子:

wl.aquire(); 

    if (true) { 
     mExecutorService.execute(thread1); 
    } 

    if (true) { 
     mExecutorService.execute(thread2); 
    } 
    wl.release(); 

因此,在這種情況下,喚醒鎖將一次2個線程已經開始或釋放它等待他們完成?

如果不是,我需要wakelock在運行時保持運行狀態,並且只有在最後一個線程結束時才釋放它。我怎樣才能做到這一點?我是否必須在線的身體內獲得新的喚醒鎖?

謝謝

回答

4

按照Executor execute()文檔:「在未來某個時間執行給定的命令,命令可以在一個新的線程中執行,在共用線,或在。調用線程,由Executor實現決定。「

因此,這取決於您使用的具體Executor。

我認爲你應該使用submit()給Executor一個新的工作。

如果你堅持使用執行器,在submit()返回的Future上調用get()將會阻塞直到結果可用。

所以,你可以撥打:

Future<Result> result_1 = mExecutorService.execute(Runnable1); 
Future<Result> result_2 = mExecutorService.execute(Runnable2); 

result_1.get(); 
result_2.get(); 

或者,你可以啓動兩個線程,等待它們完成:

Thread t1 = new Thread(Runnable1); 
Thread t2 = new Thread(Runnable2); 
t1.start(); 
t2.start(); 

t1.join(); 
t2.join(); 

希望這有助於。

+0

絕對是正確的方法。順便說一下,isnt'it executor.submit()而不是execute()? – edoardotognoni

+0

最後,我添加了一個新的wakelock部分,因爲等待執行程序獲取(),將我發送給「強制關閉,等待」問題。順便說一句,謝謝你的回答。這應該是正確的方式 – edoardotognoni

1

假設你是從AsyncTask或後臺線程運行此代碼。您可以撥打電話之前,所有線程[Thread.join()]wl.release();

退房這個linkjoin()詳細

EDIT1:在執行你也可以使用awaitTermination()與漫長的等待值等待它完成所有任務。下面的代碼是從官方java doc

void shutdownAndAwaitTermination(ExecutorService pool) { 
    pool.shutdown(); // Disable new tasks from being submitted 
    try { 
    // Wait a while for existing tasks to terminate 
    if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { 
     pool.shutdownNow(); // Cancel currently executing tasks 
     // Wait a while for tasks to respond to being cancelled 
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) 
      System.err.println("Pool did not terminate"); 
    } 
    } catch (InterruptedException ie) { 
    // (Re-)Cancel if current thread also interrupted 
    pool.shutdownNow(); 
    // Preserve interrupt status 
    Thread.currentThread().interrupt(); 
    } 
} 
+0

謝謝。這可能是一個解決方案。所以對於執行者,我們可以使用.get()命令。所以你說當啓動線程時,wakelock會立即釋放? – edoardotognoni

+0

是你的代碼喚醒鎖定會立即釋放.. –

0

請參閱http://developer.android.com/reference/android/os/PowerManager.WakeLock.html - 正確的方法是獲取正在運行的兩個線程內的喚醒鎖。鑑於你的示例代碼,你將需要內部線程1和線程的成員變量來存儲激活鎖定,以及某種方式傳遞激活鎖定的,也許是這樣的:

thread1.setWakelock(wl); 
thread2.setWakelock(wl); 

class Thread implements Runnable { 
    PowerManager.Wakelock mWakelock; 
    void setWakelock(PowerManager.Wakelock wl) { 
     mWakelock = wl; 
    } 
} 
內部線程1

然後及線程,你將需要:

run() { 
    mWakelock.acquire(); 
    ... your existing code here ... 
    mWakelock.release(); 
} 

請注意,這將工作,因爲喚醒鎖默認引用計數;請參閱PowerManager.WakeLock.setReferenceCounted()。

等待線程完成使用thread.join()是錯誤的;它會阻止UI線程,你會得到一個ANR,就像你發現的那樣。

+0

這就是我決定開發它的方式。我在它的cunstructors中使用WakeLock參數定製了一個Runnable。只需簡單地檢查它是否保持在run()方法,然後我獲得WL – edoardotognoni

相關問題