java学习多线程之生产者消费者
在java多线程当中还有一种关系需要我们来重点掌握,那就是生产者和消费者的关系。那么什么是生产者,什么是消费者呢?我们可以举个例子来说,有张三、李四负责生产烤鸭,王五、马六负责吃烤鸭,那么前者生产完烤鸭之后,如果烤鸭没有被吃完的话,这个时候就不再生产了,如果此时烤鸭吃没了,这个时候消费者就要告诉生产者,烤鸭吃没了,你要继续生产烤鸭,否则生产者一直处于等待的状态。
如何来用代码体现呢?
1、定义两个类,一个是生产者类 Product 一个是消费者类Consume,两个类分别实现Runnable中的run方法。
2、Product当中的run方法的任务就是生产烤鸭,Consume当中的run方法中就负责吃烤鸭,同时在生产完烤鸭之后,生产者就要等待,等待消费者吃完了之后就告知生产者,同理生产者生产出烤鸭之后就会告知消费者,这期间就有一个消息的传递。
在多线程当中为了让运行的线程之间能够相互通信,这个时候java提供给了我们wait()方法还有notify()方法,这两个方法的作用是,一旦wait()这个时候就释放了cup的执行权,还有执行资格,进入了冻结的状态。notify()方法却恰恰相反,他的作用是让wait()苏醒,这个时候重新拥有执行权还有执行资格。那么这两个方法是针对谁来说的呢,这个两个方法是针对锁来说的。多线程之间为什么要通信,因为有了共性的部分需要协调处理,这个时候需要通信。既然有了共同的部分这个时候,为了保证线程的安全,这个时候必然会引入一个锁来保证线程的安全,各个线程之间通过这个锁来约束,共性的部分。所以靠锁来完成进程当中的相互通信,是可靠的。
我们用代码来体现一下:
1 class KaoYa 2 { 3 4 int num = 1; 5 6 boolean flag; 7 8 Object obj = new Object(); 9 10 public void produce() 11 { 12 13 synchronized (obj) 14 { 15 while(true) 16 { 17 try{ 18 while(flag) 19 obj.wait(); 20 System.out.println(Thread.currentThread().getName()+"KaoYa...."+num); 21 flag = true; 22 obj.notify(); 23 //num++; 24 25 }catch(InterruptedException e) 26 { 27 28 } 29 } 30 31 } 32 33 } 34 35 public void consume() 36 { 37 synchronized(obj) 38 { 39 while(true) 40 { 41 try{ 42 while(!flag) 43 obj.wait(); 44 System.out.println(Thread.currentThread().getName()+"KaoYa------"+num); 45 num++; 46 flag = false; 47 obj.notify(); 48 49 }catch(InterruptedException e) 50 { 51 52 } 53 } 54 55 } 56 57 } 58 59 } 60 61 class Product implements Runnable 62 { 63 64 KaoYa k; 65 Product(KaoYa k) 66 { 67 68 this.k = k; 69 70 } 71 72 public void run() 73 { 74 75 k.produce(); 76 77 } 78 79 80 } 81 82 83 class Consume implements Runnable 84 { 85 86 KaoYa k; 87 Consume(KaoYa k) 88 { 89 90 this.k = k; 91 92 } 93 94 public void run() 95 { 96 97 k.consume(); 98 99 } 100 101 102 } 103 104 class ProCon 105 { 106 107 public static void main(String[] args) { 108 109 KaoYa k = new KaoYa(); 110 Product p = new Product(k); 111 Consume c = new Consume(k); 112 113 Thread t1 = new Thread(p); 114 Thread t2 = new Thread(c); 115 116 t1.start(); 117 t2.start(); 118 119 } 120 121 }