线程生产者与消费者
package cn.itcast.thread;
/*
线程通讯: 一个A线程完成了当前的任务时,要通知另外B线程去做另外事情。
生产者与消费者。
问题一:价格错乱问题。(线程安全问题)
问题: 目前要不就是生成一大批的产品,要不消费一大批的产品
要求的效果: 生产一个消费一个。
线程通讯相关方法:
wait() 如果一个线程调用了wait方法,那么该线程会进入以锁对象的监听器作为标识符建立的线程池中等待。 等待状态先的线程会释放锁对象。
notify() 如果一个线程调用了notify方法,那么会唤醒以锁对象的监听器建立的线程池中等待线程的其中一个。
notifyAll() 唤醒以锁对象的监听器建立线程池中 的所有等待线程。
线程通讯要注意的事项:
1. wait() ,notify() , notifyAll() 这三个方法都是属于Object类的,并不是属于Thread类的。
2. 调用wait() ,notify() , notifyAll() 这三个方法都必须要在同步函数或者是同步代码块中调用,否则报错。
3. 调用wait() ,notify() , notifyAll() 这三个方法都必须要由锁对象调用。
*/
//产品类
class Product{
String name;
int price;
boolean flag = false; //是否生产完毕的标识 false为没有生产完成 ,true 生产完毕。
}
//生产者
class Producer extends Thread{
Product p;
public Producer(Product p){
this.p = p;
}
@Override
public void run() {
int i = 0;
while(true){
synchronized (p) {
if(p.flag==false){
if(i%2==0){
p.name = "自行车";
p.price = 300;
}else{
p.name = "摩托车"; //摩托车 300
p.price = 4000;
}
System.out.println("生产者生成了"+p.name+" 价格是:"+ p.price);
//产品已经生成完毕,就应该唤醒消费者去消费。
p.flag =true;
i++;
p.notify();
}else{
try {
p.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
//消费者
class Customer extends Thread{
Product p;
public Customer(Product p) {
this.p = p;
}
@Override
public void run() {
while(true){
synchronized (p) {
if(p.flag==true){
System.out.println("消费者消费了:"+ p.name+" 价格:"+ p.price);
p.flag = false;
p.notify();
}else{
try {
p.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
public class Demo3 {
public static void main(String[] args) {
//创建一个产品对象
Product p = new Product();
//创建一个生产者对象
Producer producer = new Producer(p);
//创建消费者对象
Customer customer = new Customer(p);
//启动线程
producer.start();
customer.start();
}
}