【校招VIP】Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步

05月13日 收藏 0 评论 2 java开发

【校招VIP】Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步

文章申明:转载来源:https://blog.csdn.net/gwblue/article/details/44515931

一、概述

PV操作是对信号量进行的操作。

进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消息,当一个进程没有得到另一个进程的消息时应等待,直到消息到达才被唤醒。

举例:就像消费者与生产者的关系,说吃馒头把有一个碗能盛下6个馒头,厨师不停的生产馒头,顾客不停的吃馒头,此时厨师与顾客的关系就是同步。(如下图)

 下面我就为大家利用java多线程的代码实现这个操作的过程。

二、代码展示

1、ManTou.java

package com.gaowei.PV;

public class ManTou {

int id;
ManTou(int id) {
this.id = id;
}
public String toString() {
return "ManTou : " + id;
}
}

2、厨师类Pclient.java

package com.gaowei.PV;

public class PClient implements Runnable {

private SyncStack ss=null;
public PClient(SyncStack ss){
this.ss=ss;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
ManTou mt=new ManTou(i);
ss.push(mt);
System.out.println("生产了:"+mt);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}

3、顾客类Vclient.java

package com.gaowei.PV;

public class VClient implements Runnable {
private SyncStack ss=null;
public VClient(SyncStack ss){
this.ss=ss;
}
@Override
public void run() {
for(int i=0; i<20; i++) {
ManTou mt = ss.pop();
System.out.println("消费了: " + mt);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

4、碗类SyncStack.java

package com.gaowei.PV;

public class SyncStack {
private int index=0;
ManTou[] arrMT=new ManTou[6];

//添加馒头
public synchronized void push(ManTou mt){
while (index==arrMT.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
this.notifyAll();
arrMT[index]=mt;
index++;
}


//吃馒头
public synchronized ManTou pop(){
while(index==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrMT[index];
}
}

5、客户端显示效果代码PVClient.java

package com.gaowei.PV;

public class PVClient {

public static void main(String[] args) {

SyncStack ss = new SyncStack();
PClient p = new PClient(ss);
VClient v= new VClient(ss);

new Thread(p).start();
new Thread(v).start();
}

}

6、效果图

由于顾客吃馒头慢要6s吃个馒头,而厨师做馒头快1s就能做一个馒头。

所以从图中的分布大家就可以发现厨师做到了第6个馒头了,消费者才吃了1个馒头。

接下来由于碗中只能盛下6个馒头,所以厨师只有等着顾客吃一个,然后在放一个馒头到碗里。

一直到最后厨师20个馒头,做完了,顾客还得继续把剩下的6个馒头吃完才能结束。

三、总结

利用多线程实现了PV操作了接下了就要思考一下PV操作的好处在哪里?

在实现代码的过程中说一个细节问题:

当顾客吃了一个馒头之后,就会通知厨师这个线程来生产馒头,厨师生产一个馒头也会去通知顾客来吃馒头。

这样的思路就和观察者思路差不多能解决生产者与消费者的耦合。
说高大上点就是生产者干自己的事情,消费者干自己的事情,通过碗中消息来通知生产者该干嘛,消费者该干嘛。

这样的话就把生产者和消费者的关系解耦了。

C 2条回复 评论
烟波鬼长安

看完解析才知道应该是这样的思路

发表于 2023-09-28 21:00:00
0 0
紫侠仙子

哇,好棒啊,崇拜的小眼神

发表于 2023-06-24 22:00:00
0 0