Java实现多生产者多消费者模型

1,807 阅读2分钟

Java实现多生产者多消费者模型

信号量方式

import java.util.concurrent.Semaphore;

/**
 * Java实现多生产者-多消费者模型
 * 背景描述:父亲将苹果放入盘子,女儿从盘子里取出苹果。母亲将橘子放入盘子,儿子只吃橘子
 *
 * @author zsw
 * @date 2020/08/04 22:00
 */
public class Demo3 {
	// 对盘子进行互斥访问
	static Semaphore mutex = new Semaphore(1);
	// 盘子里的苹果信号量
	static Semaphore apple = new Semaphore(0);
	// 盘子里的橘子信号量
	static Semaphore orange = new Semaphore(0);
	// 盘子中还可以放多少个水果
	static Semaphore plate = new Semaphore(1);


	public static void main(String[] args) {
		for (int i = 0; i < 3; i++) {
			Thread dad = new Thread(new Dad());
			dad.setName("dad-" + i);
			dad.start();

			Thread daughter = new Thread(new Daughter());
			daughter.setName("daughter-1" + i);
			daughter.start();

			Thread mother = new Thread(new Mother());
			mother.setName("mother-" + i);
			mother.start();

			Thread son = new Thread(new Son());
			son.setName("son-" + i);
			son.start();
		}
	}


	static class Dad implements Runnable {
		// 父亲向盘子里放的苹果总个数
		static int setAppleNum = 0;

		@Override
		public void run() {
			while (true) {
				try {
					// 确保当前盘子可以放入东西
					plate.acquire();
					// 访问临界资源(盘子)
					mutex.acquire();
					// 苹果数量加一
					apple.release();
					setAppleNum++;
					System.out.println(Thread.currentThread().getName() + "父亲向盘子里放了第" + setAppleNum + "个苹果");
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					mutex.release();
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	static class Daughter implements Runnable {
		// 女儿从盘子里拿的苹果总个数
		static int getAppleNum = 0;

		@Override
		public void run() {
			while (true) {
				try {
					// 确保当前有苹果
					apple.acquire();
					// 访问临界区(盘子)
					mutex.acquire();
					getAppleNum++;
					System.out.println(Thread.currentThread().getName() + "女儿取出了第" + getAppleNum + "个苹果");
					// 盘子又可以放东西了
					plate.release();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					// 释放临界区
					mutex.release();
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	static class Mother implements Runnable {
		// 母亲向盘子里放的橘子总个数
		static int setOrangeNum = 0;

		@Override
		public void run() {
			while (true) {
				try {
					// 确保当前盘子可以放入东西
					plate.acquire();
					// 访问临界资源(盘子)
					mutex.acquire();
					// 苹果数量加一
					orange.release();
					setOrangeNum++;
					System.out.println(Thread.currentThread().getName() + "母亲向盘子里放了第" + setOrangeNum + "个橘子");
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					mutex.release();
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	static class Son implements Runnable {
		// 儿子从盘子里拿的橘子总数
		static int getOrangeNum = 0;

		@Override
		public void run() {
			while (true) {
				try {
					// 确保当前有橘子
					orange.acquire();
					// 访问临界区(盘子)
					mutex.acquire();
					getOrangeNum++;
					System.out.println(Thread.currentThread().getName() + "儿子取出了第" + getOrangeNum + "个橘子");
					// 盘子又可以放东西了
					plate.release();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					// 释放临界区
					mutex.release();
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

}