JAVA面试之消费者-生产者问题
来源:互联网 发布:仟游软件科技有限公司 编辑:程序博客网 时间:2024/05/18 00:22
最近遇到一个面试题,说是模拟生产者消费者问题并且不能使用concurrent包,思路是使用信号量Semaphore和PV操作,代码如下
/** * Created by violetMoon on 2016/5/12. */public class ConsumerTest { static class Semaphore { private Object lock = new Object(); private int value; public Semaphore(int value) { this.value = value; } public void p() { synchronized (lock) { value--; if (value < 0) try { System.out.println(Thread.currentThread().getName() + " go to sleep"); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public void v() { synchronized (lock) { value++; if (value <= 0) { System.out.println(Thread.currentThread().getName() + " waitup a thread"); lock.notify(); } } } } static int in; static int out; public void test() { final int BUFFER_SIZE = 5; Integer[] breads = new Integer[BUFFER_SIZE]; in = 0; out = 0; Semaphore putSema = new Semaphore(BUFFER_SIZE); //一开始缓冲区为空,所以可以填充的数量为缓冲区大小 Semaphore getSema = new Semaphore(0); //一开始没有面包 Semaphore putMutex = new Semaphore(1); Semaphore getMutex = new Semaphore(1); Runnable consumer = new Runnable() { @Override public void run() { while (true) { Integer myBread = null; getSema.p(); getMutex.p(); myBread = breads[out]; out = (out + 1) % BUFFER_SIZE; System.out.println(Thread.currentThread().getName() + " eat bread:" + myBread); getMutex.v(); putSema.v(); } } }; Runnable worker = new Runnable() { @Override public void run() { while (true) { Integer newBread = null; putSema.p(); putMutex.p(); newBread = new Integer(in); breads[in] = newBread; System.out.println(Thread.currentThread().getName() + " produce bread:" + newBread); in = (in + 1) % BUFFER_SIZE; putMutex.v(); getSema.v(); } } }; int consumerNum = 4; for (int i=0; i<consumerNum; ++i) new Thread(consumer, "consumer" + (i + 1)).start(); int workerNum = 4; for (int i=0; i<workerNum; ++i) new Thread(worker, "worker" + (i + 1)).start(); } public static void main(String[] args) { new ConsumerTest().test(); }}
Semaphore的p操作相当于获取可用资源,使用lock锁来实现value操作的原子性,以及在没有可用资源时调用lock.wait()释放当前锁并进入等待,v操作相当于释放资源,value<0表明有线程在lock上等待资源,所以调用notify释放其中一个线程
为了方便说明把putSema的资源称作写许可,把getSema的资源称作读许可。
生产者先调用putSema.p()来获取一个写许可,如果没有陷入等待,之后使用putMutex来实现生产者写互斥,进入临界区后将面包放到缓冲区里,使用putMutex.v()释放互斥锁,之后调用getSema.v()释放一个读许可。
消费者先调用getSema.p()来获取一个读许可,如果没有陷入等待,之后使用getMutex来实现消费者读互斥,进入临界区后吃掉一个面包,使用getMutex.v()释放互斥锁,之后调用putSema.p()释放一个写许可
0 0
- JAVA面试之消费者-生产者问题
- 生产者消费者问题之Java线程实现
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者问题
- java线程之生产者消费者问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java基础:多线程之生产者消费者问题
- java多线程之生产者消费者经典问题
- java学习之消费者和生产者问题
- java多线程之生产者消费者经典问题
- Java多线程之生产者/消费者问题
- JAVA线程之生产者消费者问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- JUnit4注解基本介绍
- iOS更改工程的根控制器
- 函数原型,函数声明,函数定义,他们的三角关系
- 机器学习中使用的神经网络第五讲笔记
- DOM事件流
- JAVA面试之消费者-生产者问题
- Sass 环境调试
- java线程通信
- CSS3中轻松实现渐变效果
- 7--栈的定义及实现
- How to solve this problem oC
- XML解析方式和调整jvm大小
- log4j2 转载
- 2014山东省第五届ACM省赛 Circle