一个简单的生产消费者示例

前言:打算回顾一下以前学过的知识点,先以一个小程序开始吧

  下面的代码是中午刚写的,传统的synchronized、while、wait、notifyAll的示例就不写了

 1 package com.meshuce.concurrencyTest;
 2 
 3 import java.util.LinkedList;
 4 import java.util.concurrent.TimeUnit;
 5 import java.util.concurrent.locks.Condition;
 6 import java.util.concurrent.locks.ReentrantLock;
 7 
 8 public class Test1 {
 9 
10     private static final int MAX_SIZE = 100;    
11     
12     private static LinkedList<Object> list = new LinkedList<Object>();     // 容器
13     
14     private static ReentrantLock lock = new ReentrantLock();
15     
16     private static Condition producer = lock.newCondition();
17     
18     private static Condition comsumer = lock.newCondition();
19     
20     public static void main(String[] args) {
21         
22         for (int i = 0; i < 10; i++) {    // 10个消费者
23             new Thread(()-> {
24                 
25                 for (int j = 0; j < 10; j++) {    // 每个消费者消费10个产品
26                     try {
27                         lock.lock();
28                         while(list.size() == 0) {
29                             System.out.println(Thread.currentThread().getName()+":当前有"+list.size()+"个产品,缓冲区已空,请等待生产者生产");
30                             try {
31                                 comsumer.await();    // 消费者等待
32                             } catch (InterruptedException e) {
33                                 e.printStackTrace();
34                             }
35                         }
36                         
37                         list.removeFirst();
38                         System.out.println(Thread.currentThread().getName()+":消费了一个产品,当前产品个数为 " + list.size());
39                         // 如果想看得清晰点,可以释放下面的代码段
40 //                        try {
41 //                            TimeUnit.MILLISECONDS.sleep(400);
42 //                        } catch (InterruptedException e) {
43 //                            e.printStackTrace();
44 //                        }
45                         producer.signalAll();    // 唤醒所有生产者
46                     } finally {
47                         lock.unlock();
48                     }
49                 }
50             }, "comsumer"+i).start();
51         }
52         
53 //        try {
54 //            TimeUnit.MILLISECONDS.sleep(2000);    // 等个2秒钟,让消费者都启动
55 //        } catch (InterruptedException e) {
56 //            e.printStackTrace();
57 //        }
58         
59         for (int i = 0; i < 2; i++) {    // 2个生产者
60             new Thread(()-> {
61                 
62                 for (int j = 0; j < 50; j++) {    // 每个生产者生产50个产品
63                     try {
64                         lock.lock();    // 先拿锁
65                         while(list.size() == MAX_SIZE) {
66                             System.out.println(Thread.currentThread().getName()+":当前有"+list.size()+"个产品,缓冲区已满,请等待消费者消费"); 
67                             try {
68                                 producer.await();    // 生产者等待
69                             } catch (InterruptedException e) {
70                                 e.printStackTrace();
71                             }
72                         }
73                         
74                         list.add(new Object());
75                         System.out.println(Thread.currentThread().getName()+": 生产了一个产品,当前产品个数为 " + list.size()); 
76                         
77                         // 如果想看得清晰点,可以释放下面的代码段
78 //                        try {
79 //                            TimeUnit.MILLISECONDS.sleep(200);
80 //                        } catch (InterruptedException e) {
81 //                            e.printStackTrace();
82 //                        }
83                         comsumer.signalAll();    // 唤醒所有消费者
84                     } finally {
85                         lock.unlock();
86                     }
87                 }
88             }, "producer"+i) .start();
89         }
90     }
91     
92     
93 }

 

简单提一下:

1、使用手动锁需要加 finally 进行显示地释放,否则很容易造成死锁

2、另外,yield 和 notify 的区别:在唤醒其它线程的时候,yield不会释放锁,notify会释放

转载于:https://www.cnblogs.com/Meshuce/p/8623163.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值