java多线程(生产者消费者问题)
Posted 论语孔丘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程(生产者消费者问题)相关的知识,希望对你有一定的参考价值。
生产者消费者问题是多线程的一个经典问题,描述成一块缓冲区作储存箱,生产者可以将产品放入储存箱,消费者则可以从储存箱中取走产品。
解决生产者/消费者问题的方法
采用某种机制保护生产者和消费者之间的同步
wait() / notify()方法(最高效)
wait() / nofity()方法是基类Object的两个方法:
wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等待状态,让其他线程执行。
notify()方法:当生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态。
生产者Producer.java代码如下:
1public class Producer extends Thread{
2 private String producer;
3 private Storage storage;
4 public Producer(Storage storage)
5 {
6 this.storage = storage;
7 }
8 @Override
9 public void run()
10 {
11 super.run();
12 while(true){
13 setProducer("员工"+(int)Math.ceil(Math.random()*6));
14 produce(getProducer());
15 try {
16 Thread.sleep(100);
17 } catch (InterruptedException e) {
18 e.printStackTrace();
19 }
20 }
21 }
22 public void produce(String producer)
23 {
24 storage.produce(producer);
25 }
26 public String getProducer()
27 {
28 return producer;
29 }
30 public void setProducer(String producer)
31 {
32 this.producer = producer;
33 }
34 public Storage getStorage()
35 {
36 return storage;
37 }
38 public void setStorage(Storage storage)
39 {
40 this.storage = storage;
41 }
42 }
消费者Cosumer.java代码如下:
1public class Cosumer extends Thread{
2 private String consumer;
3 private Storage storage;
4 public Cosumer(Storage storage) {
5 this.storage = storage;
6 }
7 @Override
8 public void run()
9 {
10 super.run();
11 while(true){
12 setConsumer("消费者"+(int)Math.ceil(Math.random()*1000));
13 consume(getConsumer());
14 try {
15 Thread.sleep(1000);
16 } catch (InterruptedException e) {
17 e.printStackTrace();
18 }
19 }
20 }
21 public void consume(String consumer)
22 {
23 storage.consume(consumer);
24 }
25 public Storage getStorage()
26 {
27 return storage;
28 }
29 public void setStorage(Storage storage)
30 {
31 this.storage = storage;
32 }
33 public String getConsumer() {
34 return consumer;
35 }
36 public void setConsumer(String consumer) {
37 this.consumer = consumer;
38 }
39 }
缓冲区Storage.java代码如下:
1import java.util.LinkedList;
2
3
4 import java.util.LinkedList;
5
6
7 public class Storage {
8 //储物柜最大极限
9 private final int MAX_SIZE =30;
10 //储物柜载体
11 private LinkedList<Object> list = new LinkedList<Object>();
12 //生产产品
13 public void produce(String producer){
14 synchronized (list) {
15 if (list.size() == MAX_SIZE) {
16 //如果储物柜已满
17 System.out.println("储物柜已满,"+producer+":不执行生产任务!");
18 try {
19 list.wait();//条件不足,生产堵塞,等待生产
20 } catch (InterruptedException e) {
21 e.printStackTrace();
22 }
23 }
24 //生产产品
25 list.add(new Object());//生产添加产品
26 System.out.println(""+producer+":生产了一个产品储物量为:" + list.size());
27 list.notifyAll();//生产被唤醒
28 }
29 }
30
31 public void consume(String consumer){
32 synchronized (list){
33 if (list.size() == 0) {
34 System.out.println("储物柜已空"+consumer+":不执行生产任务!");
35 try {
36
37 list.wait();
38 } catch (InterruptedException e) {
39 e.printStackTrace();
40 }
41 }
42 list.remove();//消费移除产品
43 System.out.println(""+consumer+":消费了一个产品 储物量为:" + list.size());
44 list.notifyAll();
45 }
46 }
47
48 public LinkedList<Object> getList() {
49 return list;
50 }
51 public void setList(LinkedList<Object> list) {
52 this.list = list;
53 }
54 public int getMAX_SIZE() {
55 return MAX_SIZE;
56 }
57 }
主线程Text.java代码如下:
1public class Text {
2 public static void main(String[] args) {
3 Storage storage = new Storage();
4 Producer producer = new Producer(storage);
5 Cosumer cosumert = new Cosumer(storage);
6 producer.start();
7 cosumert.start();
8 }
9}
结果如下所示:
1员工1:生产了一个产品储物量为:1
2 消费者404:消费了一个产品 储物量为:0
3 员工4:生产了一个产品储物量为:1
4 员工1:生产了一个产品储物量为:2
5 员工2:生产了一个产品储物量为:3
6 员工5:生产了一个产品储物量为:4
7 员工1:生产了一个产品储物量为:5
8 员工6:生产了一个产品储物量为:6
9 员工3:生产了一个产品储物量为:7
10员工4:生产了一个产品储物量为:8
11员工5:生产了一个产品储物量为:9
12消费者807:消费了一个产品 储物量为:8
13员工5:生产了一个产品储物量为:9
14员工4:生产了一个产品储物量为:10
15员工4:生产了一个产品储物量为:11
16员工2:生产了一个产品储物量为:12
17员工2:生产了一个产品储物量为:13
18员工1:生产了一个产品储物量为:14
以上是关于java多线程(生产者消费者问题)的主要内容,如果未能解决你的问题,请参考以下文章
JAVA基础再回首(二十五)——Lock锁的使用死锁问题多线程生产者和消费者线程池匿名内部类使用多线程定时器面试题