JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手相关的知识,希望对你有一定的参考价值。
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();
}
}
}
以上是关于JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手的主要内容,如果未能解决你的问题,请参考以下文章