生产消费者模型
基本概念:
生产消费者模型,就是存在两个线程,一个线程需要产生数据放入队列中,另一个对象需要取出数据,如果两者使用同一个缓冲区,同步处理的话,其效率就会大大减小,因为存在线程同步的问题需要处理。但是如果将生产者和消费者分开的话,生产者生产数据使用一个缓冲区,消费者使用数据用另一个缓冲区,若消费者的缓冲区中没有数据量,再把生产中的缓冲区的数据“倒”到消费者的缓冲区中,继续各自工作。如此,其效率便会大大提升。
线程同步:
要实现上述的功能,就要用到java中处理线程同步的一些类及方法。在使用这些方法之前需要了解JVM内部的结构。
如图所示:
虽然每个线程都会拥有以及创建一个属于自己的PC寄存器和JVM方法栈,但是方法区是被同一个JVM所有线程所共享的,因此两个线程同时调用相同方法时就会可能出错。
为了解决这个问题,我们就要用到java中锁的概念,若一个线程在调用这个方法时,,在该线程未使用完之前把这个方法锁起来。这时便用到关键字synchronized,代表这个方法加锁,相当于不管哪一个线程(例如生产者线程),运行到这个方法时,都要检查有没有其它线程正在用这个方法,有的话要等正在使用synchronized方法的线程运行完这个方法后再运行该生产者的线程,没有的话,就可以直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
如:public synchronized void producter(){…….方法体}
这样的话,将这整个方法都加上了一把“锁”,也就是说,一旦有一个线程在执行这个方法的时候就会将这整个方法都不能被其他线程所调用,虽然保险,然一般情况下会大大降低其线程的效率。因此,我们更多时候选择只将方法中其中一小部分易出现错误的地方锁住。
如:synchronized(syncObject) {
//允许访问控制的代码
}
这样就是将一个代码块放到里面,这块代码块在被执行时会被锁住。同时被使用的还有wait(),notify(),notifyAll().代码块可以调用wait()方法来将自身的操作挂起,直到同一个对象上的其他同步方法或同步代码块以某种方式将其改变,并调用notify()方法来通知此代码块改变已经完成。在加synchronized锁后才能调用wait(),notify(),和notifyAll().在wait()方法被调用后当前线程进入被加锁对象的线程休息室,然后释放锁,等待被唤醒。释放的锁由先前等待的另一个线程得到在获得锁后进行某种操作后通过notify或者notifyAll把原来线程从线程休息室唤醒,然后释放锁。原来被唤醒后,重新获取锁定,进行下一语句的执行。
有了上述的概念,我们就可以实现生产消费者模型。
双队列的主要代码:public class Tools {
public static list<Phone>lT = new list<Phone>(100000);
public static list<Phone>lP = new list<Phone>(100000);
}
public class DoubleBufferList {
private List<Object> IP;
private List<Object> IT;
private int gap;
/**
* 构造方法
*
* @param lP
* 用来存放对象的阻塞队列
* @param lT
* 用来取对象的阻塞队列
* @param gap
* 交换的间隔
*/
public DoubleBufferList(List IP, List IT, int gap) {
this.IP = IP;
this.IT = IT;
this.gap = gap;
}
public void check() {
Runnable runner = new Runnable() {
public void run() {
while (true) {
if (IT.size() == 0) {
synchronized (IT) {
synchronized (IP) {
IT.addAll(IP);
IP.notifyAll();
}
IP.clear();
}
}
}
}
};
Thread thread = new Thread(runner);
thread.start();
}
}
这样的双缓冲队列比一个队列的线程的效率是大大提高的。注意:
生产者队列在队列不满时进行生产
消费者队列大小为0的时候进行提取,并且进行等待
- 大小: 21.7 KB
分享到:
相关推荐
LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC...
RocketMQ生产消费者模型实现
这是一个maven+springmvc+dubbo+zookeeper的模型包括生产者、消费者、接口等。其实现可参考https://blog.csdn.net/mijichui2153/article/details/81102277。
Qt基于生产消费者模型异步访问数据库框架(不涉及数据库代码)
多线程实现生产者消费者模型:锁(Lock)、信号量(Semaphore、BoundedSemaphore)、条件(Condition)、队列(Queue)、事件(Event) 多进程程实现生产者消费者模型:信号量(Semaphore)、条件(Condition)、...
Qt入门练习项目——生产者消费者模型 Qt入门练习项目源码,通过本项目从而了解Qt,进行一个简单的入门。 本文件是对应项目源码,希望多多交流。
C++实现生产与消费者模型,利用锁实现互斥。
这是本人学习labview生产者消费者模型时,收藏的资料,里面包含生产消费者模型的文档介绍和例程,保证资源真实有效,例程能跑。
java生产者消费者模型
生产者,消费者,线程同步,模型,锁
内容:编程实现生产者-消费者问题的模拟。 基本要求: 1. 生产者消费者对缓冲区进行互斥操作。 2. 缓冲区大小为10,缓冲区满则不允许生产者生产数据,缓冲区空则不允许消费者消费数据。 3. 生产者消费者各循环操作10...
LINUX下的生产者消费者模型算法 利用进程模拟生产者消费者,利用共享存储区模拟缓冲区
基于Linux C++的条件变量实现的生产者消费者模型,旨在进一步帮助读者理解条件变量的使用。
使用wait()和notify()实现的生产者与消费者模型,可以了解如何使用wait()和notify()进行线程间通信。(上一次上传的代码有一个问题没有考虑到,这次修补了——CSDN没法撤销资源,只能再上传了)
用Qt实现的生产者消费者模型(多进程),操作系统课程作业。 4消费者,4生产者,12缓冲区,可视化展示。
大学计算机专业,操作系统实验报告,生产者消费者模型模拟进程调度
结合System V信号量机制,利用Linux下的多线程库实现了Linux下的操作系统生产者-消费者模型,具体原理可参考博文:: http://blog.csdn.net/Mikeoperfect/article/details/79431642
内容概要:基于QT Creator环境的多线程编程验证互斥的原理,通过使用semaphore,mutex等控制变量,实现对生产者消费者模型的真实模拟。 适合人群:初学操作系统的学生 能学到什么:调用了Qt多线程类库QThread进行...
有两个版本,第一个用原子操作来解决(A版本),第二个用信号量实现(B版本),新建一个文件夹,直接双击打开cpp文件调用VC6 IDE,直接编译运行即可 主要用到了windows的信号量semaphore、interLock等工具
//生产消费及辅助函数的声明 void Produce(void *p); void Consume(void *p); bool IfInOtherRequest(int); int FindProducePositon(); int FindBufferPosition(int); int main(int argc, char **argv) { //声明...