方式一:synchronized、wait和notify
1 package producerConsumer;
2 //wait 和 notify
3 public class ProducerConsumerWithWaitNofity {
4 public static void main(String[] args) {
5 Resource resource = new Resource();
6 //生产者线程
7 ProducerThread p1 = new ProducerThread(resource);
8 ProducerThread p2 = new ProducerThread(resource);
9 ProducerThread p3 = new ProducerThread(resource);
10 //消费者线程
11 ConsumerThread c1 = new ConsumerThread(resource);
12 //ConsumerThread c2 = new ConsumerThread(resource);
13 //ConsumerThread c3 = new ConsumerThread(resource);
14
15 p1.start();
16 p2.start();
17 p3.start();
18 c1.start();
19 //c2.start();
20 //c3.start();
21 }
22
23
24
25 }
26 /**
27 * 公共资源类
28 * @author
29 *
30 */
31 class Resource{//重要
32 //当前资源数量
33 private int num = 0;
34 //资源池中允许存放的资源数目
35 private int size = 10;
36
37 /**
38 * 从资源池中取走资源
39 */
40 public synchronized void remove(){
41 if(num > 0){
42 num--;
43 System.out.println("消费者" + Thread.currentThread().getName() +
44 "消耗一件资源," + "当前线程池有" + num + "个");
45 notifyAll();//通知生产者生产资源
46 }else{
47 try {
48 //如果没有资源,则消费者进入等待状态
49 wait();
50 System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");
51 } catch (InterruptedException e) {
52 e.printStackTrace();
53 }
54 }
55 }
56 /**
57 * 向资源池中添加资源
58 */
59 public synchronized void add(){
60 if(num < size){
61 num++;
62 System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有"
63 + num + "个");
64 //通知等待的消费者
65 notifyAll();
66 }else{
67 //如果当前资源池中有10件资源
68 try{
69 wait();//生产者进入等待状态,并释放锁
70 System.out.println(Thread.currentThread().getName()+"线程进入等待");
71 }catch(InterruptedException e){
72 e.printStackTrace();
73 }
74 }
75 }
76 }
77 /**
78 * 消费者线程
79 */
80 class ConsumerThread extends Thread{
81 private Resource resource;
82 public ConsumerThread(Resource resource){
83 this.resource = resource;
84 }
85 @Override
86 public void run() {
87 while(true){
88 try {
89 Thread.sleep(1000);
90 } catch (InterruptedException e) {
91 e.printStackTrace();
92 }
93 resource.remove();
94 }
95 }
96 }
97 /**
98 * 生产者线程
99 */
100 class ProducerThread extends Thread{
101 private Resource resource;
102 public ProducerThread(Resource resource){
103 this.resource = resource;
104 }
105 @Override
106 public void run() {
107 //不断地生产资源
108 while(true){
109 try {
110 Thread.sleep(1000);
111 } catch (InterruptedException e) {
112 e.printStackTrace();
113 }
114 resource.add();
115 }
116 }
117
118 }
方式二:lock和condition的await、signalAll
1 package producerConsumer;
2
3 import java.util.concurrent.locks.Condition;
4 import java.util.concurrent.locks.Lock;
5 import java.util.concurrent.locks.ReentrantLock;
6 /**
7 * 使用Lock 和 Condition解决生产者消费者问题
8 * @author tangzhijing
9 *
10 */
11 public class LockCondition {
12 public static void main(String[] args) {
13 Lock lock = new ReentrantLock();
14 Condition producerCondition = lock.newCondition();
15 Condition consumerCondition = lock.newCondition();
16 Resource2 resource = new Resource2(lock,producerCondition,consumerCondition);
17
18 //生产者线程
19 ProducerThread2 producer1 = new ProducerThread2(resource);
20
21 //消费者线程
22 ConsumerThread2 consumer1 = new ConsumerThread2(resource);
23 ConsumerThread2 consumer2 = new ConsumerThread2(resource);
24 ConsumerThread2 consumer3 = new ConsumerThread2(resource);
25
26 producer1.start();
27 consumer1.start();
28 consumer2.start();
29 consumer3.start();
30 }
31 }
32 /**
33 * 消费者线程
34 */
35 class ConsumerThread2 extends Thread{
36 private Resource2 resource;
37 public ConsumerThread2(Resource2 resource){
38 this.resource = resource;
39 //setName("消费者");
40 }
41 public void run(){
42 while(true){
43 try {
44 Thread.sleep((long) (1000 * Math.random()));
45 } catch (InterruptedException e) {
46 e.printStackTrace();
47 }
48 resource.remove();
49 }
50 }
51 }
52 /**
53 * 生产者线程
54 * @author tangzhijing
55 *
56 */
57 class ProducerThread2 extends Thread{
58 private Resource2 resource;
59 public ProducerThread2(Resource2 resource){
60 this.resource = resource;
61 setName("生产者");
62 }
63 public void run(){
64 while(true){
65 try {
66 Thread.sleep((long) (1000 * Math.random()));
67 } catch (InterruptedException e) {
68 e.printStackTrace();
69 }
70 resource.add();
71 }
72 }
73 }
74 /**
75 * 公共资源类
76 * @author tangzhijing
77 *
78 */
79 class Resource2{
80 private int num = 0;//当前资源数量
81 private int size = 10;//资源池中允许存放的资源数目
82 private Lock lock;
83 private Condition producerCondition;
84 private Condition consumerCondition;
85 public Resource2(Lock lock, Condition producerCondition, Condition consumerCondition) {
86 this.lock = lock;
87 this.producerCondition = producerCondition;
88 this.consumerCondition = consumerCondition;
89
90 }
91 /**
92 * 向资源池中添加资源
93 */
94 public void add(){
95 lock.lock();
96 try{
97 if(num < size){
98 num++;
99 System.out.println(Thread.currentThread().getName() +
100 "生产一件资源,当前资源池有" + num + "个");
101 //唤醒等待的消费者
102 consumerCondition.signalAll();
103 }else{
104 //让生产者线程等待
105 try {
106 producerCondition.await();
107 System.out.println(Thread.currentThread().getName() + "线程进入等待");
108 } catch (InterruptedException e) {
109 e.printStackTrace();
110 }
111 }
112 }finally{
113 lock.unlock();
114 }
115 }
116 /**
117 * 从资源池中取走资源
118 */
119 public void remove(){
120 lock.lock();
121 try{
122 if(num > 0){
123 num--;
124 System.out.println("消费者" + Thread.currentThread().getName()
125 + "消耗一件资源," + "当前资源池有" + num + "个");
126 producerCondition.signalAll();//唤醒等待的生产者
127 }else{
128 try {
129 consumerCondition.await();
130 System.out.println(Thread.currentThread().getName() + "线程进入等待");
131 } catch (InterruptedException e) {
132 e.printStackTrace();
133 }//让消费者等待
134 }
135 }finally{
136 lock.unlock();
137 }
138 }
139
140 }
方式三:BlockingQueue
1 package producerConsumer;
2
3 import java.util.concurrent.BlockingQueue;
4 import java.util.concurrent.LinkedBlockingQueue;
5
6 //使用阻塞队列BlockingQueue解决生产者消费者
7 public class BlockingQueueConsumerProducer {
8 public static void main(String[] args) {
9 Resource3 resource = new Resource3();
10 //生产者线程
11 ProducerThread3 p = new ProducerThread3(resource);
12 //多个消费者
13 ConsumerThread3 c1 = new ConsumerThread3(resource);
14 ConsumerThread3 c2 = new ConsumerThread3(resource);
15 ConsumerThread3 c3 = new ConsumerThread3(resource);
16
17 p.start();
18 c1.start();
19 c2.start();
20 c3.start();
21 }
22 }
23 /**
24 * 消费者线程
25 * @author tangzhijing
26 *
27 */
28 class ConsumerThread3 extends Thread {
29 private Resource3 resource3;
30
31 public ConsumerThread3(Resource3 resource) {
32 this.resource3 = resource;
33 //setName("消费者");
34 }
35
36 public void run() {
37 while (true) {
38 try {
39 Thread.sleep((long) (1000 * Math.random()));
40 } catch (InterruptedException e) {
41 e.printStackTrace();
42 }
43 resource3.remove();
44 }
45 }
46 }
47 /**
48 * 生产者线程
49 * @author tangzhijing
50 *
51 */
52 class ProducerThread3 extends Thread{
53 private Resource3 resource3;
54 public ProducerThread3(Resource3 resource) {
55 this.resource3 = resource;
56 //setName("生产者");
57 }
58
59 public void run() {
60 while (true) {
61 try {
62 Thread.sleep((long) (1000 * Math.random()));
63 } catch (InterruptedException e) {
64 e.printStackTrace();
65 }
66 resource3.add();
67 }
68 }
69 }
70 class Resource3{
71 private BlockingQueue resourceQueue = new LinkedBlockingQueue(10);
72 /**
73 * 向资源池中添加资源
74 */
75 public void add(){
76 try {
77 resourceQueue.put(1);
78 System.out.println("生产者" + Thread.currentThread().getName()
79 + "生产一件资源," + "当前资源池有" + resourceQueue.size() +
80 "个资源");
81 } catch (InterruptedException e) {
82 e.printStackTrace();
83 }
84 }
85 /**
86 * 向资源池中移除资源
87 */
88 public void remove(){
89 try {
90 resourceQueue.take();
91 System.out.println("消费者" + Thread.currentThread().getName() +
92 "消耗一件资源," + "当前资源池有" + resourceQueue.size()
93 + "个资源");
94 } catch (InterruptedException e) {
95 e.printStackTrace();
96 }
97 }
98 }