Monday, March 3, 2014

Solve Producer–consumer problem with wait() and notifyAll()

It's a example to solve the Producer–consumer problem with wait() and notifyAll().

In computing, the producer–consumer problem (also known as the bounded-buffer problem) is a classic example of a multi-process synchronization problem. The problem describes two processes, the producer and the consumer, who share a common, fixed-size buffer used as a queue. The producer's job is to generate a piece of data, put it into the buffer and start again. At the same time, the consumer is consuming the data (i.e., removing it from the buffer) one piece at a time. The problem is to make sure that the producer won't try to add data into the buffer if it's full and that the consumer won't try to remove data from an empty buffer. ~ http://en.wikipedia.org/wiki/Producer-consumer

Solve Producer–consumer problem
Solve Producer–consumer problem

package com.example.androidthread;

import java.util.LinkedList;
import java.util.Random;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

 Button buttonStart;
 TextView textInfoProducer, textInfoConsumer;

 String infoMsgProducer;
 String infoMsgConsumer;

 ShareClass shareObj = new ShareClass();
 long startingTime;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  buttonStart = (Button) findViewById(R.id.buttonstart);
  textInfoProducer = (TextView) findViewById(R.id.infoproducer);
  textInfoConsumer = (TextView) findViewById(R.id.infoconsumer);

  buttonStart.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {

    infoMsgProducer = "Producer\n";
    infoMsgConsumer = "Consumer\n";

    Thread threadProducer = new Thread(new Runnable() {

     @Override
     public void run() {
      
      int ele = 0;
      Random random = new Random();

      while (true) {
       String strEle = String.valueOf(ele);
       infoMsgProducer += strEle + "\n";
       
       MainActivity.this.runOnUiThread(new Runnable() {
        
        @Override
        public void run() {
         textInfoProducer.setText(infoMsgProducer);
        }
       });
       
       shareObj.produce(String.valueOf(ele));
       long randomDelay = 500 + random.nextInt(1000);
       
       try {
        Thread.sleep(randomDelay);
       } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
       ele++;
      }
     }
    });

    Thread threadConsumer = new Thread(new Runnable() {

     @Override
     public void run() {

      while (true) {
       Random random = new Random();

       while (true) {
        infoMsgConsumer += shareObj.consume() + "\n";
        
        MainActivity.this.runOnUiThread(new Runnable() {

         @Override
         public void run() {
          textInfoConsumer.setText(infoMsgConsumer);
         }});
        
        long randomDelay = 500 + random.nextInt(1000);
        
        try {
         Thread.sleep(randomDelay);
        } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
       }
      }
     }
    });
    
    startingTime = System.currentTimeMillis();
    threadProducer.start();
    threadConsumer.start();
   }
  });

 }

 public class ShareClass {

  final int BUFFER_MAX = 5;
  LinkedList<String> buffer;
  
  ShareClass(){
   buffer = new LinkedList<String>();
  }
  
  public synchronized void produce(String element){
   
   while(buffer.size() == BUFFER_MAX){
    try {
     wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   buffer.offer(element);
   
   notifyAll();
  }
  
  public synchronized String consume(){
   
   while(buffer.size() == 0){
    try {
     wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
   String element = buffer.poll();
   notifyAll();
   return element;
  }
 }

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/buttonstart"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start()" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/infoproducer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/infoconsumer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
        
    </LinearLayout>

</LinearLayout>




- More example about Thread

No comments: