java 与操作系统同步问题(三)————父亲儿子女儿水果问题
问题描述:父亲每次都会放一个水果在桌子上,女儿喜欢吃香蕉(只吃香蕉), 儿子喜欢吃苹果(只吃苹果)。父亲每次只会随机往桌子上放一个水果(苹果或香蕉),儿子,女儿会来取。使用p、v操作来完成父亲、儿子、女儿的同步行为模拟。
问题分析:由上述描述我们可以知道,桌子就是一个缓冲区(单缓冲),同一时刻,只能有一个人对它进行放和取得操作。所以桌子就是一个互斥信号量。而桌子上有苹果,且父亲没有放,儿子才能取,女儿也是同理。所以应该还有两个资源信号量:1 苹果 2 香蕉
在由题意分析可知,三个信号量的初始值应该为 1 0 0 因为桌子只能放一个水果。而在开始的时候,桌子上是空的(所以可以进行放的操作),所以苹果、香蕉初始资源量都为空。
代码实现:
1.信号量设定如下:
/**
* 缓冲区是否满信号量
*/
Semaphore empty; /**
* 苹果信号量
*/
Semaphore apple; /**
* 香蕉信号量
*/
Semaphore banana; empty = new Semaphore(1);
apple = new Semaphore(0);
banana = new Semaphore(0);
2.父亲的放的线程,只有在桌子互斥资源量可以用的时候才能进行放的操作。所以要先p一下桌子信号量。
Thread fatherThread = new Thread(new Runnable() {
String className = "father";
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
Semaphore.Wait(empty, className);
if (randomAB()) {
System.out.println(className + "往盘子里放了一个苹果");
Semaphore.Signal(apple, className);
} else {
System.out.println(className + "往盘子里放了一个香蕉");
Semaphore.Signal(banana, className);
}
System.out.println(className + "完成了一次放的操作");
//随机生成休眠时间,代表放入产品的操作时间
long millis = (long) (Math.random() * 1000);
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
3.儿子的实现,要判断是否有苹果,没有的话就等待
Thread sonThread = new Thread(new Runnable() {
String className = "son";
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
Semaphore.Wait(apple, className);
System.out.println(className + "从盘子里取了一个苹果");
//随机生成休眠时间,代表放入产品的操作时间
long millis = (long) (Math.random() * 1000);
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(className + "吃了一个苹果");
Semaphore.Signal(empty, className);
System.out.println(className + "完成了一次取吃的操作");
}
}
});
4.女儿的代码实现:原理跟儿子的类似
Thread daughterThread = new Thread(new Runnable() {
String className = "daughter";
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
Semaphore.Wait(banana, className);
System.out.println(className + "从盘子里取了一个香蕉");
//随机生成休眠时间,代表放入产品的操作时间
long millis = (long) (Math.random() * 1000);
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(className + "吃了一个香蕉");
Semaphore.Signal(empty, className);
System.out.println(className + "完成了一次取吃的操作");
}
}
});
运行结果如下:
daughter被阻塞
son被阻塞
father往盘子里放了一个香蕉
father资源量足够,唤醒一个
father完成了一次放的操作
daughter从盘子里取了一个香蕉
daughter吃了一个香蕉
daughter完成了一次取吃的操作
daughter被阻塞
father往盘子里放了一个香蕉
father资源量足够,唤醒一个
father完成了一次放的操作
daughter从盘子里取了一个香蕉
father被阻塞
daughter吃了一个香蕉
daughter资源量足够,唤醒一个
daughter完成了一次取吃的操作
....
java 与操作系统同步问题(三)————父亲儿子女儿水果问题的更多相关文章
- JAVA之线程同步的三种方法
最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...
- Java中实现线程同步的三种方法
实现同步的三种方法 多线程共享数据时,会发生线程不安全的情况,多线程共享数据必须同步. 实现同步的三种方法: 使用同步代码块 使用同步方法 使用互斥锁ReetrantLock(更灵活的代码控制) 代码 ...
- java面试基础题(三)
程序员面试之九阴真经 谈谈final, finally, finalize的区别: final:::修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此 ...
- Java IO:同步、非堵塞式IO(NIO)
转载请注明出处:jiq•钦's technical Blog 引言 JDK1.4中引入了NIO,即New IO,目的在于提高IO速度.特别注意JavaNIO不全然是非堵塞式IO(No-Blocking ...
- java两种同步机制的实现 synchronized和reentrantlock
java两种同步机制的实现 synchronized和reentrantlock 双11加保障过去一周,趁现在有空,写一点硬货,因为在进入阿里之后工作域的原因之前很多java知识点很少用,所以记录一下 ...
- Java中线程同步的理解
我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源, ...
- java中线程同步的理解(非常通俗易懂)
转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...
- Java 并发 线程同步
Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...
- JAVA面试之集合框架(三)
21.ArrayList和Vector的区别 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态 ...
随机推荐
- Python with
简介 在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作:当语句块执行完成后,需要继续执行一些收尾动作.例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资 ...
- 雷达的L、S、C、X波段是什么
L.S.C.X都是电磁波波段的划分代号. 最早用于搜索雷达的电磁波波长度为23cm,这一波段被定义为L波段(英语Long的字头),后来这一波段的中心波长度变为22cm. 当波长为10cm的电磁波被使用 ...
- MarkDown 常用语法教程
MarkDown 语法说明 [TOC] 标题 标题1 ====== 标题2 ----- ## 大标题 ### 小标题 #### 小标题 列表 无序列表 + 列表文本前使用 [减号+空格] * 列表文本 ...
- Hadoop之RPC简单使用(远程过程调用协议)
一.RPC概述 RPC是指远程过程调用,也就是说两台不同的服务器(不受操作系统限制),一个应用部署在Linux-A上,一个应用部署在Windows-B或Linux-B上,若A想要调用B上的某个方法me ...
- Lambda&Java多核编程-7-类型检查
本篇主要介绍Lambda的类型检查机制以及周边的一些知识. 类型检查 在前面的实践中,我们发现表达式的类型能够被上下文所推断.即使同一个表达式,在不同的语境下也能够被推断成不同类型. 这几天在码一个安 ...
- struts2 之 ServletAPI
1. 在struts2中有两种方式使用SercletAPI,一种解耦方式,一种耦合方式. 2. 解耦方式就是使用ActionContext 来实现,是完全解耦 servletAPI. ActionCo ...
- Go-Redis
redis的client有好多好多,go语言的client在redis官方有两个推荐,radix和redigo.选择哪一个好呢?确实很纠结,后来掷硬币决定选择redigo了. redis.go.red ...
- 0.0 ABP官方文档翻译目录
一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...
- OK 开始实践书上的项目一:即使标记
OK 开始实践书上的项目一:及时标记 然而....又得往前面看啦! ----------------------我是分割线------------------------ 代码改变世界
- SVD之最小二乘【推导与证明】
0.SLAM中SVD进行最小二乘的应用 在SLAM应用中,计算Homography Matrix,Fundamental Matrix,以及做三角化(Triangulation)时,都会用到最小二乘 ...