2012-03-20 73 views
1

我想知道一個監聽器應該如何讓父線程知道它已被調用。 (基本上我試圖強制異步調用是同步的。)我的例子包括Android調用,但它更多是一個普通的同步問題...如何與父線程通信已經調用了監聽器?

myMethod()方法請求SoundPool加載聲音並通知呼叫完成後的聽衆。我希望myMethod()等到偵聽器在返回之前被調用。我想出的代碼是:

void myMethod() { 
    SoundPool soundPool = ...; 
    final Lock object = new Object(); 

    soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener(){ 
     @Override 
     public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { 
      synchronized(lock) { 
       lock.notify(); 
      } 
     }}); 
    synchronized(lock) { 
     int soundId = MediaUtil.loadSoundPool(soundPool, ...); // returns immediately 
     lock.wait(); 
    } 
} 

(我離開了try/catch語句爲簡單起見,儘管它在真正的代碼)。通常情況下,我想也有兩個線程之間通信時的標誌,但我不能爲此使用局部變量,因爲它必須是最終可以從匿名類訪問的,並且實例變量看起來像是抽象違例(並且必須是易失性的)。

上述代碼是否安全和/或是否有更好的方法來解決問題?

+0

您是打算允許多個線程同時運行myMethod()或只運行一個線程? – Java42 2012-03-20 22:07:27

+0

@ChuckFricano,只有一個線程。 – 2012-03-20 22:44:48

回答

2

許多選擇來完成你所需要的。這是一種使用wait/notify的方法。 isNotified在這裏是爲了防止在調用setListener()的同一線程調用onLoadComplete()的情況下掛起。當您在查看大型應用程序的線程轉儲時,MonitorXX類將使您更容易進行調試。根據需要添加錯誤/異常/超時檢查。

static class Monitor42{boolean isNotified=false;} 
static Monitor42 monitor = new Monitor42(); 
void myMethod() { 
    synchronized(monitor) { 
     monitor.isNotified=false; 
     xxx.setListener(new Listener(){ 
     public void onLoadComplete() { 
      synchronized(monitor) { 
       monitor.isNotified=true; 
       monitor.notify(); 
      } 
     }}); 
     if (!monitor.isNotified) monitor.wait(someTimeValueMS); 
     monitor.isNotified=false; 
    } 
} 
1

基本上我試圖強制異步調用是同步的。

執行此操作的規範方法正是您在做的:在後臺線程中的異步工作結束時觸發通知,並等待主線程中的通知。

,但我不能使用局部變量用於此目的,因爲它必須是最終從匿名類

一個簡單的技巧來繞過這個限制訪問的是使用final Boolean[] flag = new Boolean[1]; flag[0] = false

+0

謝謝。兩個後續問題:1.包括國旗而不是僅僅使用wait/notify會更好嗎? 2.我是否必須將標誌變爲揮發性(或同步)以確保兩個線程看到相同的值? – 2012-03-20 22:46:50

+0

'wait/notify'或其現代替代方案可能會更好,因爲任何其他方法都需要'睡眠'。請參閱http://stackoverflow.com/questions/4912165/whats-the-best-alternative-to-wait-notify-for-low-level-synchronization。如果'sleep'沒問題,[AtomicBoolean](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicBoolean.html)更好 – 2012-03-20 23:16:43