多线程学习笔记05线程协作

new Producer(container).start();

new Consumer(container).start();

}

}

//生产者

class Producer extends Thread {

SynContainer container;

public Producer(SynContainer container) {

this.container = container;

}

//生产

@Override

public void run() {

for (int i = 1; i <= 100; i++) {

container.push(new Product(i));

}

}

}

//消费者

class Consumer extends Thread {

SynContainer container;

public Consumer(SynContainer container) {

this.container = container;

}

//消费

@Override

public void run() {

for (int i = 1; i <= 100; i++) {

container.pop();

}

}

}

//产品

class Product extends Thread {

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();

}

}

//如果容器没有满,则丢入产品

products[count] = product;

System.out.println(“生产了第” + product.id + “个产品”);

count++;

//可以通知消费者消费了

this.notifyAll();

}

//消费者消费产品

public synchronized Product pop() {

//判断能否消费

if (count == 0) {

//通知生产者生产,消费等待

try {

this.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if (count > 0) {

//可以消费

count–;

Product product = products[count];

System.out.println(“消费了第” + product.id + “个产品”);//每进来一个pop,就减一个产品

//吃完了,通知生产者生产

this.notifyAll();

return product;

} else {

//如果没有产品,直接通知生产者生产

this.notifyAll();

throw new RuntimeException(“商品不够”);

}

}

}

运行结果:

在这里插入图片描述

备注:

原出现错误的代码:

//生产者消费者模型,利用缓冲区解决:管程法

public class TestPC {

public static void main(String[] args) {

SynContainer container = new SynContainer();

new Producer(container).start();

new Consumer 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 (container).start();

}

}

//生产者

class Producer extends Thread {

SynContainer container;

public Producer(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 + “个产品”);

}

}

}

//消费者

class Consumer extends Thread {

SynContainer container;

public Consumer(SynContainer container) {

this.container = container;

}

//消费

@Override

public void run() {

for (int i = 1; i <= 100; i++) {

System.out.println(“消费了第” + container.pop().id + “个产品”);//每进来一个pop,就减一个产品

}

}

}

//产品

class Product extends Thread {

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();

}

}

//如果容器没有满,则丢入产品

products[count] = product;

count++;

//可以通知消费者消费了

this.notifyAll();

}

//消费者消费产品

public synchronized Product pop() {

//判断能否消费

if (count == 0) {

//通知生产者生产,消费等待

try {

this.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//如果可以消费

count–;

Product product = products[count];

//吃完了,通知生产者生产

this.notifyAll();

return product;

}

}

在这里插入图片描述

运行出现产品还没生产就被消费的情况,是因为程序中同时存在了3个线程,主线程、消费者、生产者,而sout语句是写在主线程中的,只要将sout语句放在各自的线程中就可以得到真实的生产-消费顺序

[](()解决方式2信号灯法

并发协作模型“生产者/消费者模式”—>信号灯法

借助标志位

  • 生产者:负责生产数据的模块(这里的模块可能是:方法、对象、线程、进程)

  • 消费者:负责处理数据的模块(这里的模块可能是:方法、对象、线程、进程)

  • 缓冲对象:生产者消费者使用同一资源,他们之间有个标志位,类似于信号灯的作用,通过信号灯控制生产者和消费者的循环使用

//信号灯法,通过标志位解决

public class TestPC2 {

public static void main(String[] args) {

TV tv = new TV();

new Player(tv).start();

new Watcher(tv).start();

}

}

//生产者:演员

class Player extends Thread {

TV tv;

public Player(TV tv) {

this.tv = tv;

}

@Override

public void run() {

for (int i = 0; i < 20; i++) {

if (i % 2 == 0) {

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值