生产者消费者问题(java多线程)

it2026-03-16  1

实验内容

(1)设置存放产品的缓冲区的个数为6个。 (2)信号量机制实现生产者和消费者对缓冲区的互斥访问。 (3)生产者生产产品时,要输出当前缓冲区冲产品的个数和存放产品的位置。 (4)消费者消费产品时,要输出当前缓冲区冲产品的个数和消费产品的位置。 (5)用多线程的并发实现生产者进程和消费者进程的同步。

实验原理

为了使生产者进程和消费之进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将其所生产的产品放入一个缓冲区中;消费者进程可以从一个缓冲区中取走产品去消费。 假定在生产者和消费者之间的公用缓冲池具有n个缓冲区,这是可以利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;利用信号量notfull和notempty分别表示缓冲池中满缓冲区和空缓冲区的数量。同时假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费之便可以从缓冲池取走一个消息。 Semaphore是一个计数信号量,它的本质是一个"共享锁"。信号量维护了一个信号量许可集。线程可以通过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。 我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。计数为0的Semaphore是可以release的,然后就可以acquire(即一开始使线程阻塞从而完成其他执行。)。

代码

class Producer implements Runnable { Clerk clerk = new Clerk(); public Producer(Clerk clerk){ this.clerk = clerk; } @Override public void run() { try { clerk.getNotFull().acquire(); clerk.getMutex().acquire(); clerk.getList().add(new Object()); System.out.println("【生产者" + Thread.currentThread().getName() + "】生产一个产品,产品存放位置为:" + clerk.getList().size() + ",现库存:" + clerk.getList().size()); } catch (Exception e) { e.printStackTrace(); } finally { clerk.getMutex().release(); clerk.getNotEmpty().release(); } } } class Consumer implements Runnable { Clerk clerk = new Clerk(); public Consumer(Clerk clerk){ this.clerk = clerk; } @Override public void run() { try { clerk.getNotEmpty().acquire(); clerk.getMutex().acquire(); clerk.getList().remove(); System.out.println("【消费者" + Thread.currentThread().getName() + "】消费一个产品,消费产品位置为:" + (clerk.getList().size() + 1) + ",现库存:" + clerk.getList().size()); } catch (Exception e) { e.printStackTrace(); } finally { clerk.getMutex().release(); clerk.getNotFull().release(); } } } import java.util.LinkedList; import java.util.concurrent.Semaphore; public class Clerk { private LinkedList<Object> list = new LinkedList<Object>(); // 仓库的最大容量 Semaphore notFull = new Semaphore(6); public void setNotFull(Semaphore notFull) { this.notFull = notFull; } public void setNotEmpty(Semaphore notEmpty) { this.notEmpty = notEmpty; } public void setMutex(Semaphore mutex) { this.mutex = mutex; } public LinkedList<Object> getList() { return list; } public void setList(LinkedList<Object> list) { this.list = list; } public Semaphore getNotFull() { return notFull; } public Semaphore getNotEmpty() { return notEmpty; } public Semaphore getMutex() { return mutex; } // 将线程挂起,等待其他来触发 Semaphore notEmpty = new Semaphore(0); // 互斥锁 Semaphore mutex = new Semaphore(1); } public class Demo_ProducerComsumer { public static void main(String[] args) { Clerk clerk = new Clerk(); int t = 12; while(t-- != 0){ new Thread(new Producer(clerk)).start(); new Thread(new Consumer(clerk)).start(); } } }

运行结果

多线程并发执行12次之后的结果,在此也可以让它while里面的参数变量为true,一直执行,方便更好的观察并发执行和互斥访问

最新回复(0)