生产者-消费者是多线程协作中非常典型的例子!
主要是生产者负责生产产品,然后消费者进行消费,但是这样的模式有几个前提
①生产者在生产前必须判断消费者线程是否占用(这里用来了加锁机制来避免发生线程安全的问题,在某一时刻内只能有一个对象在占用线程),如果线程为空闲,则才生产产品,生产完成之后,再”唤醒”消费者进行强制消费,这里有点意思啊!
②消费者在消费时,同样也要判断是否线程空闲,如果占用就一起”等待“,否则就消费产品,完成后就”唤醒“生产者进行生产产品!
下面我们将上面的思路转换为代码实现一波:
首先我们要定义一个桌子类,类中应该包含产品的数量 ,锁对象,还有产品的是否可以食用的状态:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Desk {
public static boolean flag = false;
public static int count = 10;
public static final Object lock = new Object();
}
|
然后就再定义生产者,这里的类定义为了Cooker,也是为为见名知意,Cooker类是一个线程,应该extends 线程类,然后重写run方法,写上生产的业务代码,也就是线程任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class Cooker extends Thread {
@Override public void run() { while (true) { synchronized (Desk.lock){ if (Desk.count == 0) { break; }else { if (!Desk.flag) { System.out.println("生产者正在生产产品...."); Desk.flag = true; Desk.lock.notifyAll(); }else { try { Desk.lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
|
然后就是消费者要进行消费了,线程任务和上面大致一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class Foodie extends Thread{
@Override public void run() { while (true) { synchronized (Desk.lock){ if (Desk.count == 0) { break; }else { if (Desk.flag) { System.out.println("消费者正在消费...."); Desk.flag = false; Desk.lock.notifyAll(); Desk.count--; }else { try { Desk.lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
|
最后是主线程:
1 2 3 4 5 6 7 8
| public static void main(String[] args) {
Foodie f = new Foodie(); Cooker c = new Cooker();
f.start(); c.start(); }
|
最后运行代码,看一下结果:
总结:
生产者-消费者模式主要是要对于多线程的应用场景下,要保证它的调度满足一定的规律!如有错误,请指正!