线程通讯:一个线程完成了自己的任务时,要通知另外一个线程去完成另外一个任务
public class Demo1 { public static void main(String [] args){ Product p = new Product (); Producer producer = new Producer (p); Customer customer = new Customer (p); producer.start (); customer.start (); } } class Product{ double price; String name; } class Producer extends Thread{ Product p; public Producer(Product p){ this.p = p; } public void run(){ int i =0; while(true){ if(i%2 ==0){ p.name="苹果"; try { Thread.sleep (10); } catch (InterruptedException e) { e.printStackTrace (); } p.price=6.5; }else{ p.name="香蕉"; p.price=2.0; } System.out.println ("生产者生产了:"+p.name+" 价格是:"+p.price); i++; } } } class Customer extends Thread{ Product p; public Customer(Product product){ this.p = product; } public void run(){ while(true){ System.out.println ("消费者消费了:"+p.name+" 价格是:"+p.price); } } }
消费者消费了:苹果 价格是:2.0 消费者消费了:苹果 价格是:2.0 消费者消费了:苹果 价格是:2.0 消费者消费了:苹果 价格是:2.0 消费者消费了:苹果 价格是:2.0
解决价格错乱问题-加synchronized关键字
public class Demo { public static void main(String [] args){ Product p = new Product (); Producer producer = new Producer (p); Customer customer = new Customer (p); producer.start (); customer.start (); } } class Product{ double price; String name; } class Producer extends Thread{ Product p; public Producer(Product p){ this.p = p; } public void run(){ int i =0; while(true){ synchronized (p) { if (i % 2 == 0) { p.name = "苹果"; try { Thread.sleep (10); } catch (InterruptedException e) { e.printStackTrace (); } p.price = 6.5; } else { p.name = "香蕉"; p.price = 2.0; } System.out.println ("生产者生产了:" + p.name + " 价格是:" + p.price); i++; } } } } class Customer extends Thread{ Product p; public Customer(Product product){ this.p = product; } public void run(){ while(true) { synchronized (p) { System.out.println ("消费者消费了:" + p.name + " 价格是:" + p.price); } } } }
要求:
生产者生产完一个产品之后就要等待消费者去消费,然后在生产,
消费者消费完一个产品之后就要等待生产者去生产
wait() 等待 如果线程执行了wait方法那么该线程会进入等待的状态,等待状态下的线程必须调用notify 方法才能唤醒
notify()唤醒 唤醒等待的线程
wait与notify要注意的事项
1、wait 方法与notify 方法是属于object对象的
2、wait 方法与notify方法必须要在同步代码块或者是同步函数中才能使用
3、wait方法与notify方法必须要有锁对象调用。
public class SaleTicket { public static void main(String [] args){ Product p = new Product (); Producer producer = new Producer (p); Customer customer = new Customer (p); producer.start (); customer.start (); } } class Product{ double price; String name; boolean flag = false;//产品生产完毕的标志,默认是没有生产完毕的 } class Producer extends Thread{ Product p; public Producer(Product p){ this.p = p; } public void run(){ int i =0; while(true){ synchronized (p) { if(p.flag ==false) { if (i % 2 == 0) { p.name = "苹果"; try { Thread.sleep (10); } catch (InterruptedException e) { e.printStackTrace (); } p.price = 6.5; } else { p.name = "香蕉"; p.price = 2.0; } System.out.println ("生产者生产了:" + p.name + " 价格是:" + p.price); i++; p.flag=true; p.notify ();//唤醒消费者去消费 }else{ //已经生产完毕,等待消费者先去消费 try { p.wait (); } catch (InterruptedException e) { e.printStackTrace (); } } } } } } class Customer extends Thread{ Product p; public Customer(Product product){ this.p = product; } 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) { e.printStackTrace (); } } } } } }
生产者生产了:苹果 价格是:6.5 消费者消费了:苹果 价格是:6.5 生产者生产了:香蕉 价格是:2.0 消费者消费了:香蕉 价格是:2.0