Java多生产者和多消费者互斥同步问题

Adam_cumt 2010-08-04 08:36:08
有一只铁笼子,每次只能放入一只动物,猎手向笼中放入老虎,农民向笼中放入猪,动物园等待取笼中的老虎,饭店等待取笼中的猪,试用Java中的P、V操作写出能同步执行的程序.

题目的实质是:两个生产者和两个消费者共享了一个仅能存放一件产品的缓冲器,生产者各自生产不同的产品,消费者各自取自己需要的产品。请高手给出程序。
...全文
326 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
CoderPlusPlus 2010-08-05
  • 打赏
  • 举报
回复
JAVA代码来了,已测试通过,顺便复习下同步知识

import java.util.Random;
import java.util.concurrent.Semaphore;

public class SynchronizeTest {
//看了文档之后才知道JAVA1.5以后已经有Semaphore了
//对于这个例子由于笼子容量为1,所以只用wait和notify也是可以的,笼子容量更大时就要用到信号量了
Semaphore sCage = new Semaphore(1);
Semaphore sTiger = new Semaphore(1);
Semaphore sPig = new Semaphore(1);
Random rnd = new Random(System.currentTimeMillis());

public void test() {
try {
//初始时笼子里没有动物
sTiger.acquire();
sPig.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new HunterThread().start();
new FarmerThread().start();
new ZooThread().start();
new HotelThread().start();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new SynchronizeTest().test();
}

class HunterThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
for (;;) {
try {
//为了方便看输出,加入延时
System.out.println("紧张激烈地打猎中...");
sleep(rnd.nextInt(5000));
sCage.acquire();
System.out.println("========放入老虎========");
sTiger.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

class FarmerThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
for (;;) {
try {
System.out.println("紧张激烈地喂猪中...");
sleep(rnd.nextInt(5000));
sCage.acquire();
System.out.println("========放入猪========");
sPig.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

class ZooThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
for (;;) {
try {
sTiger.acquire();
System.out.println("========取出老虎========");
sCage.release();
System.out.println("老虎表演中...");
sleep(rnd.nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

class HotelThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
for (;;) {
try {
sPig.acquire();
System.out.println("========取出猪========");
sCage.release();
System.out.println("红烧肉制作中...");
sleep(rnd.nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

gaoxulaiguo 2010-08-05
  • 打赏
  • 举报
回复
用阻塞队列可以的吧
CoderPlusPlus 2010-08-05
  • 打赏
  • 举报
回复
这不是操作系统教材上典型的吃苹果吃橘子问题么

SC = 1 //
ST = 0 //
SP = 0 //

//猎手进程
for(;;) {
P(SC);
put(tiger);
V(ST);
}

//农夫进程
for(;;) {
P(SC);
put(pig);
V(SP);
}

//动物园进程
for(;;) {
P(ST);
get(tiger);
V(SC);
}

//饭店进程
for(;;) {
P(SP);
get(pig);
V(SC);
}

以上是伪码实现,要真正用JAVA实现的话用wait()和notify()来实现PV操作即可
z_free 2010-08-05
  • 打赏
  • 举报
回复
来此学习
lostmymain 2010-08-05
  • 打赏
  • 举报
回复
学习学习
zhaining522 2010-08-05
  • 打赏
  • 举报
回复
这个的并发性 肯定不高

1个锁 4个线程去竞争 。。。。

avalon 2010-08-05
  • 打赏
  • 举报
回复
这个例子不少,楼主网上搜索一下就有很多方法,1楼采用文件锁也是不错的做法。
「已注销」 2010-08-04
  • 打赏
  • 举报
回复
更正:
动物园和饭店的判断条件
while(isEmpty() ||
「已注销」 2010-08-04
  • 打赏
  • 举报
回复 1
生产者,只用判断是否为空即可
消费者,先判断是否为空。如果不为空则peek出来,检测是否是自己需要的类型,如果不是,则不消费,释放锁

伪码
猎手:
syn(lock){
while(!isEmpty())
lock.wait();
put(tiger);
lock.notifyAll();
}

农民:
syn(lock){
while(!isEmpty())
lock.wait();
put(pig);
lock.notifyAll();
}

动物园:
syn(lock){
while(!isEmpty() || !(peek() instanceof Tiger))
lock.wait();
getTiger();
lock.notifyAll();
}
饭店:
syn(lock){
while(!isEmpty() || !(peek() instanceof Pig))
lock.wait();
getPig();
lock.notifyAll();
}

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧