Java实现⽣产者消费者问题(信号量机制)
⾸先,先讲⼀下⽣产者消费者问题的本质,其实就是同步和互斥的问题。
所谓同步问题,其实这个名词,容易让⼈迷惑,同步,是同时的意思吗?其实不是,反⽽是不同时的意思。同步问题,其实就是⼀前⼀后的问题,某个进程或者程序,必须在另⼀个的前⾯或者后⾯执⾏,他俩不能同时执⾏,就是这个意思。
毕业论文中期报告如果说同步是对进程或者程序的执⾏顺序的规定。那么互斥问题,其实更多是对某个资源的规定,即某个资源不能同时被两个进程占⽤。就⽐如说⽣产者消费者问题中,⽣产者占⽤缓冲区往缓冲区放产品的时候,消费者就不能⽤缓冲区,此时,缓冲区对⽣产者和消费者就是⼀个互斥问题。
好了,理解了同步和互斥,就容易理解⽣产者消费者问题了。⾸先,互斥关系:⽣产者和消费者对缓冲区的访问是互斥关系。同步关系:⽣产者和消费者⼜是互相是对⽅的同步关系,只有⽣产者⽣产了产品,消费者才能消费,也只有消费者消费了产品,⽣产者才能再⽣产。
信号量是⼀种功能很强的机制,可以⽅便解决同步互斥问题。底层由两个原语构成:wait和signal,即操作系统中解决同步问题的PV操作。因为本⼈对操作系统学的⽐较多,因此,想⽤信号量来解决Java中⽣产者消费者问题,没想到Java中真的内置有信号量机制,真是万能的Java!
下⾯上代码:
public class ProduceAndConsumer {
//缓冲区初始化为0
private static Semaphore full =new Semaphore(0);
//空闲缓冲区,假如为5
徐州云龙湖风景区
private static Semaphore empty =new Semaphore(5);
// 互斥锁
private static Semaphore mutex =new Semaphore(1);
//⽤⼀个list来模拟⽣产和消费过程,因为需要频繁增删,所以⽤链表
private static LinkedList<Object> list=new LinkedList<>();
//⽣产者
有关雪的成语
public void produce()throws InterruptedException {
//获取空缓冲区
成长中的烦恼
empty.acquire();
//进⼊临界区
mutex.acquire();
//⽣产数据
资料室管理制度
list.add(new Object());中国名茶排行榜前十名
//离开临界区,释放互斥信号量
//提供产品,产品缓冲区+1
饥饿疗法
}
//消费者
public void consumer()throws InterruptedException {
//获取满缓冲区
full.acquire();
//进⼊临界区
mutex.acquire();
团的成语
//消费数据
//离开临界区,释放互斥信号量
/
/提供产品,产品缓冲区+1
}
}
两个同步信号量:full和empty,分别⽤来实现⽣产者和消费者的同步关系,假设缓冲区初始为5,这个可以随意更改。
⼀个互斥信号量:mutex,⽤来实现对缓冲区的互斥访问。