消费者线程
package com.bjsxt.commu5;/*** 消费者线程*/
public class ConsumeRunnable implements Runnable {//private Product product = new Product();private Product product;private Object obj = new Object();public ConsumeRunnable() {}public ConsumeRunnable(Product product) {this.product = product;}public void setProduct(Product product) {this.product = product;}@Overridepublic void run() {while(true){product.consume();}}
}
生产者线程
package com.bjsxt.commu5;/*** 生产者线程*/
public class ProduceRunnable implements Runnable {//private Product product = new Product();private Product product;public ProduceRunnable() {}public ProduceRunnable(Product product) {this.product = product;}public void setProduct(Product product) {this.product = product;}@Overridepublic void run() {int i = 0;while(true){product.produce(i);i++;}}
}
产品
package com.bjsxt.commu5;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 商品类*/
public class Product {private String name;//名称 馒头 玉米饼private String color;//颜色 白色 黄色boolean flag = false;//默认没有商品private Lock lock = new ReentrantLock();private Condition produceCondition = lock.newCondition();private Condition consumeCondition = lock.newCondition();public Product() {}public Product(String name, String color) {this.name = name;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", color='" + color + '\'' +'}';}/*** 生产一个商品*/public void produce(int i){//thislock.lock();try{//1.如果已经有商品,就等待if(flag){try {//this.wait();produceCondition.await();} catch (InterruptedException e) {e.printStackTrace();}}//2. 生产商品并输出if(i%2 ==0 ){//product.setName("馒头");this.name = "馒头";try {Thread.sleep(10); //只释放cpu不释放锁} catch (InterruptedException e) {e.printStackTrace();}//product.setColor("白色");this.color = "白色";}else{//product.setName("玉米饼");this.name = "玉米饼";try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//product.setColor("黄色");this.color = "黄色";}System.out.println("生产者生产一个商品:"+name+" "+color);//3.改变商品有无的状态:有商品了this.flag = true;//4.通知消费//this.notify();//随机的唤醒一个线程(目前只有两个,被唤醒的肯定是消费者)consumeCondition.signal();}finally {lock.unlock();}}/*** 消费一个商品*/public void consume(){//thislock.lock();try{//1.如果没有商品,就等待if(!flag){try {//this.wait(); //让出了cpu,也让出了锁//wait();consumeCondition.await();} catch (InterruptedException e) {e.printStackTrace();}}//2.消费商品System.out.println("消费者消费一个商品:"+name+" "+color);//3.改变商品的有无状态:无this.flag = false;//4.通知生产者生产//this.notifyAll();//唤醒所有等待的线程(目前所有等待的线程只有一个,就是消费者)produceCondition.signalAll();}finally {lock.unlock();}}}
main
package com.bjsxt.commu5;public class Test {public static void main(String[] args) {Product product = new Product();//创建线程对象Runnable runnable1 = new ProduceRunnable(product);Thread thread1 = new Thread(runnable1);ConsumeRunnable runnable2 = new ConsumeRunnable();runnable2.setProduct(product);Thread thread2 = new Thread(runnable2);//启动线程thread1.start();thread2.start();}
}
遇到的问题及解决方案:
- 问题1:生产和消费没有交互
- 解决:线程通信…
- 问题2:和商品没有关系
- 解决:定义一个商品类
- 问题3:生产者可以交替的生产,但是消费者消费的一直是null
- 解决:保证生产者生产和消费者消费的是同一个商品
- 问题4:出现了白色的玉米饼和黄色的馒头
- 解决:需要进行线程同步
- 问题1:生产和消费没有交互
- 解决:线程通信…
- 使用从Object类继承的wait() notify() notifyAll()方法实现通信
- 注意事项: 必须调用同步监视器的wait() notify() notifyAll()方法
-
product.wait();
-
product.notify();
-
product.notifyAll();