2013-05-08 58 views
0

我試圖瞭解與此線程併發編程,我似乎並沒有得到這個等待()和notify()Android的Java的通知不會觸發等待

我懷疑它是與我的一個線程永遠在等待,通知已被調用。但我不知道如何解決這個問題。我通過其他人閱讀了stackoverflow上的帖子,但無法理解。

這是我的代碼,如果有人能指出我朝着正確的方向,這將是有幫助的。

package com.example.thread_android; 

import android.os.Bundle; 
import android.app.Activity; 
import android.util.Log; 
import android.view.Menu; 

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Log.d("Stage", "onCreate"); 

    Runnable AthreadJob = new ARunnable(); 
    Runnable BthreadJob = new BRunnable(); 
    Thread myThreadOne = new Thread(AthreadJob); 
    Thread myThreadTwo = new Thread(BthreadJob); 
    myThreadOne.start(); 
    myThreadTwo.start(); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 
} 

class ARunnable implements Runnable{ 
@Override 
public void run(){ 
    Log.d("Runnable", "A Inside Run - WAIT"); 
    try{ 
     synchronized(this){wait();} 
    } catch (InterruptedException e) {} 
    //Log.d("Runnable", "A Inside Run - CONTINUE"); 
} 
} 

class BRunnable implements Runnable{ 
@Override 
public void run(){ 
    Log.d("Runnable", "B Inside Run"); 
    synchronized (this) {notify();} 
} 
} 
+4

不要從學習等待和通知開始。這些太低級了。學習使用java.util.concurrent包中的更高級抽象。如果你真的想使用wait和notify,至少要閱讀他們的javadoc,這就清楚地解釋了它們是如何使用的,尤其是等待必須總是在循環中使用,並且等待的線程會被通知,如果另一個線程調用通知()與用於等待的對象相同的對象。 – 2013-05-08 12:06:41

+0

你應該更改與同步(MainActivity.this)同步(this)並接受@Stephen回答 – Blackbelt 2013-05-08 12:22:37

+0

感謝您的有用評論@JB Nizet – 2013-05-08 12:50:33

回答

1

在代碼

class ARunnable implements Runnable{ 
@Override 
public void run(){ 
    Log.d("Runnable", "A Inside Run - WAIT"); 
    try{ 
     synchronized(this){wait();} 
    } catch (InterruptedException e) {} 
    //Log.d("Runnable", "A Inside Run - CONTINUE"); 
} 
} 

this裝置的ARunnable正在運行的實例。此實例實際上是線程監視器對象線程鎖定/解鎖以執行同步塊),並且您已將當前線程詢問爲wait();

爲了讓等待的線程喚醒並再次運行,其他線程,抱着同一監視器(I,E的ARunnable相同的實例)應該調用notify()notifyAll();。像下面的東西

class ARunnable implements Runnable{ 
    boolean ready = false; 
    //setter for ready.. 
    @Override 
    public void run(){ 
     Log.d("Runnable", "A Inside Run - WAIT"); 
     try{ 
      synchronized(this){ 
       if(!ready) { 
         wait(); 
       } 
       else { 
        notifyAll(); // Now the thread which was waiting earlier, will wake-up and start resuming the execution. 
       } 
      } 
     } catch (InterruptedException e) {} 
     //Log.d("Runnable", "A Inside Run - CONTINUE"); 
    } 
    } 
2

JB Nizet的建議是健全的。不要使用wait/notify開始學習多線程。你應該從更高的信號機制開始;例如信號量,鎖存器,期貨等。

但是,您的代碼在wait()ARunnable.run中被阻止的原因在BRunnable.run中沒有看到notify()是等待和通知正在不同的對象上執行。如果你想要一個「可運行」信號發送另一個,他們需要一個共享對象,他們都需要synchronize在該對象上,並調用wait()notify就可以了。