`
fanrey
  • 浏览: 252216 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java Semaphore 实例 -- Hungry Birds

    博客分类:
  • JAVA
 
阅读更多
The Hungry Birds Problem  (one producer - multiple consumers)
Given are n baby birds and one parent bird. The baby birds eat out of a common dish that initially contains W worms. Each baby bird repeatedly takes a worm, eats it, sleeps for a while, takes another worm, and so on. If the dish is empty, the baby bird that discovers the empty dish chirps real loud to awaken the parent bird. The parent bird flies off and gathers W more worms, puts them in the dish, and then waits for the dish to be empty again. This pattern repeats forever.
Develop and implement a multithreaded program to simulate the actions of the birds. Represent the birds as concurrent threads (i.e. array of "babyBird" threads and a "parentBird" thread), and the dish as a critical shared resource that can be accessed by at most one bird at a time. Use only semaphores for synchronization. Your program should print a trace of interesting simulation events. Is your solution fair? Explain in comments to the source code.



import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class HungryBirds
{
public static List<String> wormBuffer = new ArrayList<String>();

public static int WORM_NUMBER = 10;
public static int BIRD_NUMBER = 5;

public static Semaphore semaphoreBufParent = new Semaphore(1);
public static Semaphore semaphoreBufChild = new Semaphore(0);
public static Semaphore semaphoreBuffer = new Semaphore(1);

public static void main(String[] args)
{

ParentBird producer = new ParentBird();
producer.start();

for ( int i=0; i<BIRD_NUMBER; i++ )
{
ChildBird consumer = new ChildBird(i);
consumer.start();
}


}
}

class ParentBird extends Thread
{

public ParentBird()
{
}

public void run()
{
while (true)
{


// try to acquire a semaphore if the buffer is not full
try
{
HungryBirds.semaphoreBufParent.acquire();
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}

List<String> buffer = HungryBirds.wormBuffer;

try {
HungryBirds.semaphoreBuffer.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}

for(int i=0; i<HungryBirds.WORM_NUMBER; i++){
String worm = "Worm " + i;
buffer.add( worm );
}
System.out.println("Parent bird produced worms! Worm number is " + buffer.size() + "!");
HungryBirds.semaphoreBuffer.release();

HungryBirds.semaphoreBufChild.release();

try
{
Thread.sleep( 1000 );
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

class ChildBird extends Thread
{
private int id;

public ChildBird( int id )
{
this.id = id;
}

public void run()
{
String worm = null;
while (true)
{
// try to acquire a semaphore if the buffer is not empty
try
{
HungryBirds.semaphoreBufChild.acquire();
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
// this consumer thread is accessing the shared buffer...

try {
HungryBirds.semaphoreBuffer.acquire();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
List<String> buffer = HungryBirds.wormBuffer;
int count = buffer.size();
if(count == 0){
HungryBirds.semaphoreBufParent.release();

}
else{
worm = buffer.get( count-1 );
buffer.remove( count-1 );
System.out.println("Bird " + id + " ate one worm:" + worm +"!");

HungryBirds.semaphoreBufChild.release();
}
HungryBirds.semaphoreBuffer.release();

try
{
Thread.sleep( 1 );
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics