2011-08-16 8 views
1

私は単純なプロデューサー/コンシューマーのサンプルをAndroidでテストしています。Android(Java)プロデューサー/コンシューマー(タイマー付)

私は2つのEditTextボックスを持っています.1つはプロデューサ、もう1つはコンシューマです。このボタンを2回押すと、消費者が消費している間にプロデューサが生成すると、このアプリケーションは単一のボタンも持ちます。ここに私のコードは次のとおりです。

他の方法のための今
submit.setOnClickListener(new View.OnClickListener() { 

@Override 
public void onClick(View v) { 
    Timer producerTimer = new Timer(); 
    producerTimer .schedule(new TimerTask(){ 
    @Override 
    public void run(){ 
    producer(); 
    } 
    },100, 300); 

    Timer consumerTimer = new Timer(); 
    consumerTimer .schedule(new TimerTask(){ 
    @Override 
    public void run(){ 
    consumer(); 
    } 
    },100, 300); 
} 
}); 

} 

:ここ

public void producer(){ 
    this.runOnUiThread(producer_Tick); 
} 

public void consumer(){ 
    this.runOnUiThread(consumer_Tick2); 
} 

private Runnable producer_Tick = new Runnable(){ 
    public void run(){ 
     put(i++); 

    } 
}; 

private Runnable consumer_Tick= new Runnable(){ 
    public void run(){ 
     int result = get(); 
     consumerBox.append(Integer.toString(result) + "\n"); 

    } 
}; 

は私の同期メソッドです:

public synchronized void put(int val){ 
    if (!empty){ 
     try{ 
      wait(); 
     }catch (InterruptedException e) {Log.d(TAG,"Error Putting");} 
    } 

    producerBox.append(Integer.toString(val) + "\n"); 
    empty = false; 
    buffer=val; 
    notify(); 
} 

public synchronized int get(){ 
    if (empty){ 
     try{ 
      wait(); 
     }catch (InterruptedException e) {Log.d(TAG,"Error getting");} 
    } 

    empty = true; 
    notify(); 
    return buffer; 

} 

このプログラムは、ランダムな点にすべての時間を実行します。時にはいくつかのミニスイートでは、消費者がプロデューサーなどから読む場所でうまくいく。しかし、いつも、ある時点で、プログラムはプロデューサーとコンシューマーで特定の値(毎回ランダム)で凍りつくだろう。上記のコードに誰かが問題を見ていますか?

答えて

2

プロデューサ/コンシューマスレッド間の通信に、より効率的でわかりやすい方法でblocking queueを使用する必要があります。

+0

おかげさまで、あなたが必要なもののように聞こえるでしょう。しかし、私は本当にそれを自分のコードに組み込む方法がわからないのですが、どうやってそのようなことができるのか知っていますか? –

+0

@MarkもしあなたがJavaのドキュメントを見れば。プロデューサとコンシューマのタイマーの間に1つの「キュー」を作成して共有する必要があります。 'producer()'は 'queue.put'を実行し、' consumer() 'は' queue.take'を実行します。 UI要素を更新しているときにのみ 'runOnUIThread'を呼び出します –

0

notifyAll()を使用する必要があります。 notifyはどのスレッドに通知されているのかわかりません。また、空のハットが実際に同期されていることを確認します(getとputが存在するステータスクラスが所有しています)。