黑马程序员_2_多线程之生产者与消费者
------- android培训、java培训、期待与您交流! ----------
多线程通讯问题解析:
我们要了解生产者与消费者问题,首先要明白,多线程执行的流程即生命周期。
文字如下:
调用了sleep、wait方法的时候
<----------临时阻塞<----------
调用start方法 抢到了cpu的执行权 执行完毕任务
创建--------------> 可运行状态 ----------------->运行状态-------------->死亡
<----------------
被抢夺了cpu的执行权
图列如下:
线程通讯:一个线程完成自己的任务后告诉另一个线程执行他自己的任务。
下面我们来看看线程通讯问题实例-----生产者与消费者:
首先描述一个产品类。
package cn.chen.runndom;//描述一个产品类。class Product {String name;//产品名double price;//产品价格boolean flag =false;//是否生产完标记,默认为false表示没有生产完,true已经生产完毕了。//无参的构造方法。public Product() {}public Product(String name, double price) {this.name = name;this.price = price;}}
然后描述一个生产者。
package cn.chen.runndom;//描述一个生产者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){if(i%2==0){p.name="苹果";p.price=5.5;}else{p.name="香蕉";p.price=1.5;}System.out.println("生产者已经生产了"+p.name+"价格是:"+p.price);//改变标记。让生产者先停止,等待消费完p.flag=true;//唤醒线程池中正在等待的线程p.notify();i++;}else{try {//线程进入线程池中等待被唤醒p.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
描述一个消费者:
package cn.chen.runndom;class Customer extends Thread{//消费者类维护了一个产品类Product p;//通过构造函数传递产品,保证与生产者是同一个产品对象public Customer(Product p) {this.p = p;}//消费者线程执行的任务public void run(){//线程同步代码块,解决价格错乱问题。synchronized (p) {while(true){if(p.flag){System.out.println("消费者消费了"+p.name+"价格是:"+p.price);p.flag=false;//唤醒线程池中等待的线程p.notify();}else{try {p.wait();//线程进入线程池等待被唤醒。} catch (InterruptedException e) {e.printStackTrace();}}}}}}
现在万事俱备,创建线程并开启。
package cn.chen.runndom;public class mainTest {public static void main(String[] args) {//创建产品对象。Product product = new Product();//创建生产者线程对象。把产品对象通过构造方法传递Producer producer = new Producer(product);//创建消费者线程对象、把产品对象通过构造方法传递Customer customer = new Customer(product);//调用start方法开启线程。producer.start();customer.start();}}
输出结果。
从输出结果可以看出,生产者每生产完一个产品,消费者就会消费一个产品。
线程通讯中:
wait();线程等待,如果一个线程调用了该方法,那么该方法就会进入等待状态,必须要其他线程唤醒,才能重新进入可运行状态。
notily();唤醒等待线程中的一个线程。
注意:这俩个方法都是上帝Object类中的方法。必须在同步代码块或者同步函数中调用。且
必须使用锁对象调用。
一个线程执行了wait方法的时候,那么该线程会进入一个以锁对象为标识符的一个线程池等待。
一个线程执行了notify方法的时候,会唤醒线程池中等待线程的其中一个线程,
注意:执行wait方法的时候是会释放锁对象,
线程执行sleep方法的时候不会释放锁对象。所以要使用wait方法。
本文详细介绍了多线程中的生产者与消费者模型实现方式。通过具体代码示例展示了如何利用Java中的synchronized关键字及wait和notify方法来实现线程间的通讯。

482

被折叠的 条评论
为什么被折叠?



