1,问题描述
问题描述:编写Windows下父亲儿子女儿放取水果进程同步的演示程序。(问题描述:桌上有一空盘,最多允许存放一个水果。爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。 试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。提示:设置一个信号量表示可否向盘中放水果,一个信号量表示可否取桔子,一个信号量表示可否取苹果。
在解决进程同步问题中,有一种方式叫做信号量机制,即通过信号量来将不同的进程进行控制和使用,使其避免出现死锁现象。
在本题中,父亲放水果,儿子拿苹果,女儿拿香蕉都是不同的进程,可以在不同的时间允许和操作。但如何进行,这就是要解决的问题。
2,Java中的信号量是java.util.concurrent.Semaphore
函数实现的。
信号量
Semaphore
通过使用计数器counter
来控制对共享资源的访问。如果计数器大于零,则允许访问。如果为零,则拒绝访问。计数器对共享资源的访问许可进行计数。因此,要访问资源,线程必须要从信号量得到许可。
Semaphore 的构造函数有两种:
Semaphore(int num)
Semaphore(int num, boolean how)
其中的
num
,表示指定初始的许可计数。因此,它也就指定了一次可以同时访问共享资源的线程数。如果是1
,那么同时只能有一个线程可以访问该资源。默认情况下,所有等待的线程都以未定义的顺序被授予许可
。通过设置how为true
,可以确保等待线程按其请求访问的顺序被授予许可
。
该函数会使用到的方法有,Semaphore.acquire()
,获取信号量的控制权的锁,类比于P
操作,Semaphore.release()
,释放信号量的控制锁,类比于V
操作。
关于信号量的博客:Java中的信号量Semaphore
下面开始使用,这本题中设置,3个信号量:
static Semaphore empty = new Semaphore(1,true);//资源区是否为空
static Semaphore apple = new Semaphore(0,true);//资源区苹果信号
static Semaphore banana = new Semaphore(0,true);//资源区香蕉信号
第一个empty
信号量表示,盘中是否有水果,也是对于父亲的放水果的操作的控制。apple
信号量,用于儿子的拿苹果的操作,banana
用于女儿拿香蕉的操作。
3,父亲的相关代码:
//父亲的进程
Thread father = new Thread(new Runnable() {
public void run() {
while (true) {
try {
empty.acquire();//申请操作权限相当于wait(S)
int random = Math.random() >= 0.5 ? 1 : 0;
if (random == 1) {
System.out.println("父亲放入了一个苹果");
Thread.sleep(1000);//休眠表示放入的过程
apple