java 消费对象_JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手...

因为觉得把方法写到店员类里面,总是很怪异,不符合面向对象编程里面,谁的行为谁做。

package com.home.nxj.ProTest;

public class ProTest {

public static void main(String[] args) {

Clerk ck = new Clerk();

Productors p1 = new Productors(ck);

Concumers c1 = new Concumers(ck);

Thread t1 = new Thread(p1);

Thread t2 = new Thread(c1);

t1.start();

t2.start();

}

}

//店员类,这里只提供一个产品信息。或者改为仓库类更合适

class Clerk{

//里面只有一个属性,产品的剩余数字。protected,同包类可以访问

protected int productCount = 0;

}

//用实现Runnable接口的方式,重写生产者消费者关系例子。

class Productors implements Runnable {

//和店员类的联系属性

private Clerk waiter;

//带参构造器,实现和店员类,或者说仓库类的关联关系

public Productors(Clerk waiter) {

this.waiter = waiter;

}

//没啥好说的,Runnable接口实现后,重写run()方法。

@Override

public void run() {

while (true) {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

//用synchrinized()函数来包装需要线程同步的代码。

synchronized (waiter) {

if (waiter.productCount < 20) {

waiter.productCount++;

System.out.println(Thread.currentThread().getName() + ":开始生产xx第" + waiter.productCount + "个产品");

//这里因为线程监控器不是this,所以不可以直接调用notify()。谁作为线程监控器,就由谁去调用notify()和wait()。

//notify();直接调用会报错:java.lang.IllegalMonitorStateException

waiter.notify();

} else {

try {

waiter.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

}

class Concumers implements Runnable {

private Clerk waiter;

public Concumers(Clerk waiter) {

this.waiter = waiter;

}

@Override

public void run() {

while (true) {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (waiter) {

if (waiter.productCount > 0) {

System.out.println(Thread.currentThread().getName() + ":开始消费xx第" + waiter.productCount + "个产品");

waiter.productCount--;

waiter.notify();

} else {

try {

waiter.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

}

对比视频上看来的传统写法:

package com.home.nxj.ProductTest;

public class ProductTest {

public static void main(String[] args) {

Waiter waiter = new Waiter();

Productor p1 = new Productor(waiter);

p1.setName("生产者1");

Customer c1 = new Customer(waiter);

c1.setName("消费者");

p1.start();

c1.start();

}

}

class Waiter{

private int productCount = 0;

//生产产品

public synchronized void produceProduct() {

if (productCount < 20){

productCount ++;

System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount +"个产品");

notify();

}else {

//等待

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

//消费产品

public synchronized void consumeProduct() {

if (productCount > 0){

System.out.println(Thread.currentThread().getName() + ":开始消费" + productCount + "个产品");

productCount --;

notify();

}else {

//等待

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

class Productor extends Thread{

private Waiter waiter;

public Productor(Waiter waiter) {

this.waiter = waiter;

}

@Override

public void run() {

System.out.println(getName() + ":开始生产产品" );

while (true){

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

waiter.produceProduct();

}

}

}

class Customer extends Thread{

private Waiter waiter;

public Customer(Waiter waiter) {

this.waiter = waiter;

}

@Override

public void run() {

System.out.println(getName()+ ":开始消费...");

while (true){

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

waiter.consumeProduct();

}

}

}

原文:https://blog.51cto.com/accole/2480630

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生产者消费者问题是一个经典的多线程问题,主要涉及到共享资源的问题。在该问题中,生产者消费者共享一个缓冲区,生产者向缓冲区中生产产品,而消费者从缓冲区中消费产品。由于缓冲区的大小有限,因此需要进行同步控制,以避免生产者在缓冲区已满时继续生产,或者消费者在缓冲区为空时继续消费。 下面是一个使用 Java 实现生产者消费者问题的示例代码,其中生产者消费者类都继承了 Runnable 类,并给出了注释。 ```java import java.util.LinkedList; public class ProducerConsumerDemo { public static void main(String[] args) { // 创建一个共享缓冲区 LinkedList<Integer> buffer = new LinkedList<Integer>(); // 创建两个生产者和两个消费者 Producer producer1 = new Producer(buffer); Producer producer2 = new Producer(buffer); Consumer consumer1 = new Consumer(buffer); Consumer consumer2 = new Consumer(buffer); // 创建四个线程并启动 new Thread(producer1).start(); new Thread(producer2).start(); new Thread(consumer1).start(); new Thread(consumer2).start(); } // 生产者类 static class Producer implements Runnable { private LinkedList<Integer> buffer; private int maxSize = 10; public Producer(LinkedList<Integer> buffer) { this.buffer = buffer; } public void run() { while (true) { synchronized (buffer) { // 如果缓冲区已满,等待消费者消费 while (buffer.size() == maxSize) { try { System.out.println("缓冲区已满," + Thread.currentThread().getName() + " 等待消费"); buffer.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 生产一个产品,并通知消费者消费 int product = (int) (Math.random() * 100); buffer.add(product); System.out.println(Thread.currentThread().getName() + " 生产了产品 " + product); buffer.notifyAll(); } // 生产完一个产品后休眠一段时间 try { Thread.sleep((int) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } } // 消费者类 static class Consumer implements Runnable { private LinkedList<Integer> buffer; public Consumer(LinkedList<Integer> buffer) { this.buffer = buffer; } public void run() { while (true) { synchronized (buffer) { // 如果缓冲区为空,等待生产者生产 while (buffer.isEmpty()) { try { System.out.println("缓冲区为空," + Thread.currentThread().getName() + " 等待生产"); buffer.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 从缓冲区中取出一个产品,并通知生产者生产 int product = buffer.removeFirst(); System.out.println(Thread.currentThread().getName() + " 消费了产品 " + product); buffer.notifyAll(); } // 消费完一个产品后休眠一段时间 try { Thread.sleep((int) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } } } ``` 在该示例代码中,我们使用了 LinkedList 来作为共享缓冲区。生产者消费者类都实现Runnable 接口,并重写了 run() 方法。在 run() 方法中,我们使用 synchronized 和 wait()、notifyAll() 来进行同步控制。当缓冲区已满时,生产者等待消费者消费;当缓冲区为空时,消费者等待生产者生产。同时,为了模拟实际情况,我们在生产和消费产品之后都加上了一定的休眠时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值