http://www.cnblogs.com/DreamDrive/p/6192685.html 这个是用synchronized关键字实现的.

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. public Food(String id) {
  6. this.id = id;
  7. }
  8.  
  9. public String getId() {
  10. return id;
  11. }
  12.  
  13. public void setId(String id) {
  14. this.id = id;
  15. }
  16.  
  17. }

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. }

线程中消费者生产者的实例代码(使用Lock类)的更多相关文章

  1. 线程中消费者生产者的实例代码(synchronized关键字)

    http://www.cnblogs.com/DreamDrive/p/6204665.html  这个是用Lock类实现的. 场景: 厨师类: import java.util.List; impo ...

  2. Java线程中的join使用实例

    JDK中解释为 Waits for this thread to die. 等待本线程结束后,下一个线程才可以运行. 实例要求: 现在有T1.T2.T3三个线程,你怎样保证T2在T1执行完后执行,T3 ...

  3. Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  4. Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  5. 《Lua程序设计》9.2 管道(pipe)与过滤器(filter) 包含使用协同函数实现“生产者——消费者”问题的实例代码

    一个关于协同程序的经典示例是“生产者-消费者”问题.这其中涉及到两个函数,一个函数不断地产生值(比如从一个文件中读取值),另一个则不断地消费这些值(比如将这些值写到另一个文件).通常,这两个函数大致是 ...

  6. 详解 HTML5 中的 WebSocket 及实例代码-做弹幕

    原文链接:http://www.php.cn/html5-tutorial-363345.html

  7. java-多线程的练习----妖,等待唤醒,代码重构,lock到condition

    1 需求 资源有姓名和性别. 两个线程,    一个负责给姓名和性别赋值,    一个负责获取姓名和性别的值. 要求1,运行一下,解决程序的 "妖"的问题. 要求2,实现正确数据的 ...

  8. Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)

    1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...

  9. Java子线程中的异常处理(通用)

    在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何正确捕获子线程中的异常,从而进行相 ...

随机推荐

  1. python模块:pickle

    """Create portable serialized representations of Python objects. See module copyreg f ...

  2. devexpress 的combobox怎样只能选择不能输入

    我们知道listbox和combobox的区别就是listbox是下拉列表框,只能下拉,不支持在listbox中自定义输入,而combobox是textbox和listbox的合体,被称为组合框. c ...

  3. 安卓TP驱动开发

    转自 blog.csdn.net/dddxxxx/article/details/54312415

  4. matlab画无向图,基于坐标的无向图联系作者

    %函数名netplot %使用方法输入请help netplot %无返回值 %函数只能处理无向图 %作者:tiandsp %最后修改: function netplot(A,flag) %调用方法输 ...

  5. asp.net DataReader DataTable 使用反射给给实体赋值

    asp.net 使用反射给给实体赋值 实体类继承此基类 using System.Reflection; using System.Data.SqlClient; using System.Data; ...

  6. Topcoder-SRM-#712-Div2

    250-RepeatNumberCompare Problem Statement For any two positive integers x and k we can make a new nu ...

  7. silverlight 父窗体传值给ChildWindow

    在网上找了许多列子,有的没有看懂,有的太麻烦. 现在有两种方法又简单又实用的,分享给大家! 第一种:使用构造函数传值 1.子页面新建一个构造函数 public ChildWindowTest(stri ...

  8. web-day1

    第1章   WEB01-HTML篇 今日任务 网站信息页面案例 网站图片信息页面案例 网站友情链接页面案例 网站首页案例 网站注册页面案例 网站后台页面案例 教学导航 教学目标 了解什么是标记语言 了 ...

  9. android ActivityGroup接收不到onActivityResult

    android 框架嵌套,用viewgroup是很好用的.首先实现一个框架的activity,可以继承ActivityGroup 将需要切换的界面,放到ViewGroup里面. 切换如下: Inten ...

  10. POJ 1191棋盘分割问题

    棋盘分割问题 题目大意,将一个棋盘分割成k-1个矩形,每个矩形都对应一个权值,让所有的权值最小求分法 很像区间DP,但是也不能说就是 我们只要想好了一个怎么变成两个,剩下的就好了,但是怎么变,就是变化 ...