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();
}
}
}
}
分享到:
相关推荐
Semaphore T-BOX System OverviewPDF,Semaphore T-BOX System Overview
在解读了文档《Semaphore T-Box RTU.pdf》的内容后,我们可以梳理出以下与Semaphore T-Box RTU相关的知识点: 首先,Semaphore T-Box RTU是一个先进的远程终端单元(RTU),它首次将复杂的IP/Web技术平台引入到远程...
### 信号量同步等待机制(Semaphore Wait-and-Signal) #### 一、引言 在多线程编程中,临界资源的访问管理是一项至关重要的任务。为了确保数据的一致性和程序的正确执行,必须采取有效的机制来防止多个线程同时...
7. **并发工具类**:`java.util.concurrent`包提供了丰富的并发工具,如`Semaphore`(信号量)、`CountDownLatch`(计数器)、`CyclicBarrier`(栅栏)和`Phaser`(同步屏障),用于控制并发流程。 8. **并发模式**...
JAVA多线程--信号量(Semaphore) 信号量(Semaphore)是一种多线程环境下的设施,负责协调各个线程,以保证它们能够正确、合理地使用公共资源。从概念上讲,信号量维护了一个许可集。 信号量的类型有两种:单值信号...
并发编程是现代多线程应用的基础,手册会详细讲解Java的线程管理,包括线程的创建与启动、同步机制(如synchronized关键字、volatile变量、Lock接口)、并发工具类(如ExecutorService、Semaphore、CountDownLatch)...
Java并发库提供了多种工具类,如`ReentrantLock`、`Semaphore`和`Condition`,这些可以帮助我们更安全地管理并发,减少死锁发生的可能性。 8. **线程通信**: 使用`wait()`、`notify()`和`notifyAll()`方法进行...
这是一个关于使用Java进行实例开发的源码包,源自GitHub,并且与Java API的使用密切相关。这个压缩包"dlinsin-github-java-api-5f7e387"可能包含了某个特定版本或分支的代码,其中"5f7e387"很可能是Git仓库中的一个...
在Java编程中,多线程是并发编程的重要组成部分,它允许程序同时执行多个任务,从而提高了系统的效率和响应性。然而,在某些场景下,我们可能需要控制线程的执行顺序,确保它们按照特定的顺序交替运行,这在并发编程...
开发者可以通过创建Thread对象或者实现Runnable接口来启动新线程,`java.util.concurrent`包提供了高级并发工具,如ExecutorService、Semaphore和CountDownLatch等。 5. **I/O与NIO**:`java.io`提供了传统的输入...
在这个"semaphore-develop.zip"压缩包中,包含的应该是Semaphore的开发源码,这对于理解其内部工作原理、自定义功能或贡献代码到开源项目来说是极其宝贵的资源。 Semaphore的核心特性在于它的可视化部署服务,它...
12. **Java应用实例**:通过实际项目,如开发简单的桌面应用、Web应用或移动应用,让学生将所学知识应用于实践中。 这个Java课程设计项目应该包含了上述所有主题的详细讲解,通过阅读源代码、文档和完成练习,学习...
Kubernetes的Semaphore CI / CD演示 这是一个示例应用程序和CI / CD管道,展示了如何使用Semaphore 2.0将微服务构建,测试和部署...docker run -p 80:4567 semaphore-demo-ruby-kubernetes curl localhost > hello worl
10. **并发编程**:Java并发API如Semaphore、CountDownLatch、CyclicBarrier等工具类,以及并发容器如ConcurrentHashMap、CopyOnWriteArrayList等,都是面试的重点。 11. **Spring框架**:作为企业级开发的主流框架...
源码中可能会包含这些基本元素的实例,帮助学习者理解如何在实际项目中运用。 2. **类与对象** Java是面向对象的语言,其核心是类和对象的概念。源码中可能包含类的定义、对象的创建、封装、继承、多态等OOP特性,...
15. **并发编程**:Java提供了丰富的并发工具类,如CountDownLatch、CyclicBarrier、Semaphore等,实例将展示如何高效地管理并发任务。 通过逐一研究这些源码实例,不仅可以加深对Java语言的理解,还能提升实际编程...
《Java2 Tutorial-5.0》是一份针对Java 2平台第五版(也称为Java 5.0)的详尽教程,旨在帮助开发者深入理解和掌握Java编程语言的关键概念和技术。这个教程涵盖了广泛的Java编程主题,从基础语法到高级特性,为初学者...
这部分可能讲解了线程的创建、同步机制(如synchronized关键字,wait()和notify()方法,以及Lock接口)、线程池(ExecutorService)和并发工具类(如Semaphore、CountDownLatch、CyclicBarrier)。 2. **反射**:...
Java提供了多种同步机制来解决多线程环境下的数据安全问题,如synchronized关键字、 volatile变量、Lock接口(如ReentrantLock)以及Semaphore信号量等。synchronized提供了内置锁,可以保证同一时刻只有一个线程...
Java以其强大的并发支持闻名,这部分可能讲解了如何创建和管理线程,包括Thread类和Runnable接口的使用,线程同步机制(如synchronized关键字,wait()、notify()和notifyAll()方法),以及高级的并发工具类,如...