利用JDK中的BlockingQueue数据结构特性可以模拟出操作系统中生产者消费者互斥与同步关系
BlockingQueue的数据结构特性
put(Object):把一个Object对象加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续
take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入
这是两个比较重要的内置方法,也是本次实验要用到的两个方法,根据这两个方法就可以模拟出操作系统中资源缓冲区所进行的PV操作。
生产者消费者PV操作模型
生产者模型
消费者模型
代码段
消费者模拟出处理一个进程需花费随机数时间
/**
* 消费者线程
* @author sunYuhan
*
**/
class ConsumerThread extends Thread {
private Resource resource;
public ConsumerThread(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
try {
Thread.sleep((long) (1000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.remove();
}
}
}
生产者模拟随机时间产生进程
/**
* 生产者线程
* @author sunYuhan
*
**/
class ProducerThread extends Thread{
private Resource resource;
public ProducerThread(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
try {
Thread.sleep((long) (1000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.add();//像资源缓冲区中添加资源
}
}
}
将BlockingQueue 及其操作封装进Resouce类中
/**
* 资源缓冲区
* @author sunYuhan
*
**/
class Resource{
private BlockingQueue resourceQueue = new LinkedBlockingQueue(10);
/**
* 向资源池中添加资源
*/
public void add(){
try {
resourceQueue.put(1);
System.out.println("生产者" + Thread.currentThread().getName()
+ "生产一件资源," + "当前资源池有" + resourceQueue.size() +
"个资源");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 向资源池中移除资源
*/
public void remove(){
try {
resourceQueue.take();
System.out.println("消费者" + Thread.currentThread().getName() +
"消耗一件资源," + "当前资源池有" + resourceQueue.size()
+ "个资源");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
主函数,多线程模拟多个进程
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 生产者消费者模型
* 武汉理工大学计算机学院-孙煜晗
*
*/
//使用阻塞队列BlockingQueue解决生产者消费者
public class BlockingQueueConsumerProducer {
public static void main(String[] args) {
Resource resource = new Resource();
//生产者线程
ProducerThread p1 = new ProducerThread(resource);
ProducerThread p2 = new ProducerThread(resource);
ProducerThread p3 = new ProducerThread(resource);
//多个消费者
ConsumerThread c1 = new ConsumerThread(resource);
ConsumerThread c2 = new ConsumerThread(resource);
ConsumerThread c3 = new ConsumerThread(resource);
p1.start();
p2.start();
p3.start();
c1.start();
c2.start();
c3.start();
}
}