1、多线程问题:生产者消费者问题
问题描述:有两个对象,一个是生产者,一个是消费者。生产者负责生产产品,消费者负责消耗产品。两者之前需要同步,消费的前提是有产品。生产的前提是有空间存储。
代码如下:
/*
* 利用缓冲区解决生产者消费者问题模型--管程法
* 需要四个角色
* 1、生产者 2、消费者 3、产品 4、缓冲区
* */
public class test13 {
public static void main(String[] args) {
SynContainer synContainer = new SynContainer();
new Producter(synContainer).start();
new Consumer(synContainer).start();
}
}
//消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了"+container.pop().id+"只鸡");
}
}
}
//生产者
class Producter extends Thread{
SynContainer container;
public Producter(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
container.push(new Product(i));
System.out.println("生产了"+i+"只鸡");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//产品
class Product{
int id;
public Product(int id) {
this.id = id;
}
}
//容器
class SynContainer{
Product[] products=new Product[10];// 容器大小
int count=0;//容器计数器
//生产者放入产品
public synchronized void push(Product product){
if(count==products.length){//判断容器内部是否有产品
//通知消费者消费,生产等待
try {
this.wait();//消费者等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
//如果没有满,我们需要丢入产品
products[count]=product;
count++;
//可以通知消费者消费了
this.notifyAll();
}
}
//消费者消费产品
public synchronized Product pop(){
if(count==0){//判断如果容器内没有产品则等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
Product product=products[count];
this.notifyAll();//通知生产者生产
return product;
}
}
根据操作系统同步机制写的一个代码:
package com.jackly.main.ch12;
public class test14 {
public static void main(String[] args) {
Stock stock=new Stock();
new Producter1(stock).start();
new Consumer1(stock).start();
}
}
//生产者
class Producter1 extends Thread{
public Producter1(Stock stock) {
this.stock = stock;
}
Stock stock;
@Override
public void run() {
for (int i = 0; i < 20; i++) {
stock.push();
}
}
}
//消费者
class Consumer1 extends Thread{
public Consumer1(Stock stock) {
this.stock = stock;
}
Stock stock;
@Override
public void run() {
for (int i = 0; i < 20; i++) {
stock.pop();
}
}
}
//缓冲区
class Stock{
private int full=0;//表示已存入缓冲区个数
private int empty=10;//表示当前剩余缓冲区大小
public synchronized void push(){
if (empty==0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if(empty<=10){//判断当前剩余缓冲器大小,如果为10,则放入产品
full++;
empty--;
System.out.println("缓冲区有"+full+"个产品");
this.notifyAll();
}
}
public synchronized void pop() {//消费者消费
if(full==0){//判断缓冲区内是否有产品,如果为0,则通知生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
full--;
empty++;
System.out.println("当前缓冲区还剩"+full+"个产品");
this.notifyAll();
}
}
}
信号灯法解决消费者生产者模型问题:解决思路:设置一个布尔类型的值表示当前缓冲区是否可操作,如果缓冲区内无产品则信号为false,通知生产者生产产品,如果缓冲区内有产品但是已经达到满值,则信号灯为true并判断是否满值,暂停生产者生产,通知消费者消费。代码略。