线程中消费者生产者的实例代码(使用Lock类)

简介:

 

Lock可以替换synchronized.

上面用来做为锁对象的SaleWindow.class没有别的操作,而且获取锁和释放锁都是在内部隐藏完成的.

Java的思想是万物皆对象,我们把这种锁也描述成为一个对象,就是Lock.....

Lock中的lock和unlock显式的打开和关闭(可视化)更直观.

Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作.

此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的Condition对象.

 

Lock可以替换synchronized.

 使用synchronized

synchronized(SaleWindow.class) {

 

}

SaleWindow.class 这个锁对象没有别的操作,而且这个锁对象获取锁和释放锁的操作都是在内部隐藏的完成的,而Java的思想是万物皆对象.

我们把这种锁也描述成了一个对象,这个对象就是Lock.

Lock中获取锁和释放锁都提供了对应的方法,这两种操作都是一种显式的操作,更直观的表示了这个问题.

 

如果仅仅把之间的synchronized替换成Lock运行是会报错的.

 

原因就是锁替换了synchronized 但是wait只能在同步中调用.

我们应该把wait 和 notify 等待唤醒机制都替换掉.

 

上面说的Condition是将Object监视器方法(wait,notify和notifyAll)分解成截然不同的对象,以便通过这些对象与任意Lock实现组合使用,为每个对象提供多个等待...其中Lock替代了synchronized方法和语句的使用,Condition替代了Object监视器方法的使用.

Condition中有await()  signal()  和 signalAll().....

 

SaleWindow.java

复制代码
 1 import java.util.List;
 2 import java.util.Random;
 3 import java.util.concurrent.TimeUnit;
 4 import java.util.concurrent.locks.Condition;
 5 import java.util.concurrent.locks.Lock;
 6 
 7 public class SaleWindow implements Runnable {
 8 
 9     private List<Food> foods;
10 
11     public List<Food> getFoods() {
12         return foods;
13     }
14 
15     public void setFoods(List<Food> foods) {
16         this.foods = foods;
17     }
18 
19     public SaleWindow(List<Food> foods) {
20         this.foods = foods;
21     }
22 
23     public SaleWindow() {
24     }
25 
26     public void sale() {
27         while (true) {
28             // 加锁
29             Lock lock = MyLock.LOCK;
30             Condition cook_con =  MyLock.COOK_CON;
31             Condition sale_con =  MyLock.SALE_CON;
32             lock.lock();
33             if (foods.size() > 0) {
34                 try {
35                     Food food = foods.get(0);
36                     System.out.println(Thread.currentThread().getName()
37                             + ": 卖出了 " + food.getId() + " 号饭...");
38                     Random ran = new Random();
39                     int i = ran.nextInt(300);
40 
41                     TimeUnit.MILLISECONDS.sleep(i);
42                     foods.remove(0);
43                     // SaleWindow.class.notify();//随机唤醒一条等待的线程
44                     cook_con.signal();
45                 } catch (InterruptedException e) {
46                     e.printStackTrace();
47                 }
48             } else {
49                 System.out.println(Thread.currentThread().getName()
50                         + ":饭买完了。厨师赶紧做,我休息了。。。");
51                 try {
52                     sale_con.await();
53                 } catch (InterruptedException e) {
54                     e.printStackTrace();
55                 }
56 
57             }
58             // 释放锁
59             lock.unlock();
60         }
61     }
62 
63     @Override
64     public void run() {
65         sale();
66     }
67 
68 }
复制代码

  Cook.java

复制代码
 1 import java.util.List;
 2 import java.util.Random;
 3 import java.util.concurrent.TimeUnit;
 4 import java.util.concurrent.locks.Condition;
 5 import java.util.concurrent.locks.Lock;
 6 
 7 public class Cook implements Runnable {
 8 
 9     private List<Food> foods;
10     private static int num = 1;
11     private static final int MAXSIZE = 1;
12 
13     public List<Food> getFoods() {
14         return foods;
15     }
16 
17     public void setFoods(List<Food> foods) {
18         this.foods = foods;
19     }
20 
21     public Cook(List<Food> foods) {
22         this.foods = foods;
23     }
24 
25     public Cook() {
26     }
27 
28     public void produce() {
29         while (true) {
30             Lock lock = MyLock.LOCK;
31             Condition cook_con =  MyLock.COOK_CON;
32             Condition sale_con =  MyLock.SALE_CON;
33             lock.lock();
34             if (foods.size() < MAXSIZE) {
35                 Food food = new Food((num++) + "");
36                 foods.add(food);
37                 System.out.println(Thread.currentThread().getName() + " :做好 "
38                         + food.getId() + " 号饭了");
39                 Random ran = new Random();
40                 int i = ran.nextInt(300);
41                 try {
42                     TimeUnit.MILLISECONDS.sleep(i);
43                 } catch (InterruptedException e) {
44                     e.printStackTrace();
45                 }
46 
47                 // SaleWindow.class.notify();
48 
49                 sale_con.signal();//唤醒等待中的一条线程
50             } else {
51                 System.out.println(Thread.currentThread().getName()
52                         + " :桌子放满了。窗口赶紧卖,我休息了。。。");
53 
54                 try {
55                     cook_con.await();
56                 } catch (InterruptedException e) {
57                     e.printStackTrace();
58                 }
59             }
60             lock.unlock();
61         }
62 
63     }
64 
65     @Override
66     public void run() {
67         produce();
68     }
69 }
复制代码

 Food.java

复制代码
 1 public class Food {
 2 
 3     private String id;
 4 
 5     
 6     public Food(String id) {
 7         this.id = id;
 8     }
 9 
10     public String getId() {
11         return id;
12     }
13 
14     public void setId(String id) {
15         this.id = id;
16     }
17     
18     
19 }
复制代码

 MyLock.java

复制代码
 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.Lock;
 3 import java.util.concurrent.locks.ReentrantLock;
 4     //把锁抽取出来.
 5 public class MyLock {
 6     
 7     public static final Lock LOCK = new ReentrantLock(true);//公平模式
 8     public static final Condition COOK_CON = LOCK.newCondition();//监视Cook的监视器
 9     public static final Condition SALE_CON = LOCK.newCondition();//监视Sale的监视器 
10     //两个监视器之间可以相互通知 本方唤醒对方的等待中的一条线程.
11     
12     //构造方法私有 单例  饿汉式
13     private MyLock(){}
14 }
复制代码

 Test.java

复制代码
 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 public class Test {
 5 
 6     public static void main(String[] args) {
 7         
 8         /*List<Food> foods = new ArrayList<Food>();
 9         for (int i = 0; i < 10; i++) {
10             foods.add(new Food((i+1)+""));
11         }
12         Restaurant r = new Restaurant(foods);
13         for (int i = 0; i < 3; i++) {
14             new Thread(r).start();
15         }*/
16         List<Food> foods = new ArrayList<Food>();
17         for (int i = 0; i < 4; i++) {
18             new Thread(new Cook(foods),"Cook"+(i+1)).start();
19         }
20         for (int i = 0; i < 3; i++) {
21             new Thread(new SaleWindow(foods),"sale"+(i+1)).start();
22         }
23     }
24 }
复制代码

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/6204665.html,如需转载请自行联系原作者

相关文章
|
1月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
1月前
|
安全 Java 容器
线程安全的集合类
线程安全的集合类
|
1月前
多线程案例-定时器(附完整代码)
多线程案例-定时器(附完整代码)
|
1月前
|
存储 缓存 安全
【C/C++ 关键字 存储类说明符 】 线程局部变量的魔法:C++ 中 thread_local的用法
【C/C++ 关键字 存储类说明符 】 线程局部变量的魔法:C++ 中 thread_local的用法
33 0
|
14天前
|
存储 安全 Java
java多线程之原子操作类
java多线程之原子操作类
|
16天前
|
Java
Java中的多线程实现:使用Thread类与Runnable接口
【4月更文挑战第8天】本文将详细介绍Java中实现多线程的两种方法:使用Thread类和实现Runnable接口。我们将通过实例代码展示如何创建和管理线程,以及如何处理线程同步问题。最后,我们将比较这两种方法的优缺点,以帮助读者在实际开发中选择合适的多线程实现方式。
21 4
|
18天前
|
Java Spring
springboot单类集中定义线程池
该内容是关于Spring中异步任务的配置和使用步骤。首先,在启动类添加`@EnableAsync`注解开启异步支持。然后,自定义线程池类`EventThreadPool`,设置核心和最大线程数、存活时间等参数。接着,将线程池bean注入到Spring中,如`@Bean(&quot;RewardThreadPool&quot;)`。最后,在需要异步执行的方法上使用`@Async`注解,例如在一个定时任务类中,使用`@Scheduled(cron = &quot;...&quot;)`和`@Async`结合实现异步定时任务。
15 2
|
27天前
|
Linux API C++
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
51 2
|
1月前
|
消息中间件 并行计算 网络协议
探秘高效Linux C/C++项目架构:让进程、线程和通信方式助力你的代码飞跃
探秘高效Linux C/C++项目架构:让进程、线程和通信方式助力你的代码飞跃
34 0
|
1月前
|
安全 C++ 开发者
【C++多线程同步】C++多线程同步和互斥的关键:std::mutex和相关类的全面使用教程与深度解析
【C++多线程同步】C++多线程同步和互斥的关键:std::mutex和相关类的全面使用教程与深度解析
18 0

热门文章

最新文章