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

 import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock; public class SaleWindow implements Runnable { private List<Food> foods; public List<Food> getFoods() {
return foods;
} public void setFoods(List<Food> foods) {
this.foods = foods;
} public SaleWindow(List<Food> foods) {
this.foods = foods;
} public SaleWindow() {
} public void sale() {
while (true) {
// 加锁
Lock lock = MyLock.LOCK;
Condition cook_con = MyLock.COOK_CON;
Condition sale_con = MyLock.SALE_CON;
lock.lock();
if (foods.size() > 0) {
try {
Food food = foods.get(0);
System.out.println(Thread.currentThread().getName()
+ ": 卖出了 " + food.getId() + " 号饭...");
Random ran = new Random();
int i = ran.nextInt(300); TimeUnit.MILLISECONDS.sleep(i);
foods.remove(0);
// SaleWindow.class.notify();//随机唤醒一条等待的线程
cook_con.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName()
+ ":饭买完了。厨师赶紧做,我休息了。。。");
try {
sale_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
} }
// 释放锁
lock.unlock();
}
} @Override
public void run() {
sale();
} }

Cook.java

 import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock; public class Cook implements Runnable { private List<Food> foods;
private static int num = 1;
private static final int MAXSIZE = 1; public List<Food> getFoods() {
return foods;
} public void setFoods(List<Food> foods) {
this.foods = foods;
} public Cook(List<Food> foods) {
this.foods = foods;
} public Cook() {
} public void produce() {
while (true) {
Lock lock = MyLock.LOCK;
Condition cook_con = MyLock.COOK_CON;
Condition sale_con = MyLock.SALE_CON;
lock.lock();
if (foods.size() < MAXSIZE) {
Food food = new Food((num++) + "");
foods.add(food);
System.out.println(Thread.currentThread().getName() + " :做好 "
+ food.getId() + " 号饭了");
Random ran = new Random();
int i = ran.nextInt(300);
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
} // SaleWindow.class.notify(); sale_con.signal();//唤醒等待中的一条线程
} else {
System.out.println(Thread.currentThread().getName()
+ " :桌子放满了。窗口赶紧卖,我休息了。。。"); try {
cook_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.unlock();
} } @Override
public void run() {
produce();
}
}

Food.java

 public class Food {

     private String id;

     public Food(String id) {
this.id = id;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} }

MyLock.java

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

Test.java

 import java.util.ArrayList;
import java.util.List; public class Test { public static void main(String[] args) { /*List<Food> foods = new ArrayList<Food>();
for (int i = 0; i < 10; i++) {
foods.add(new Food((i+1)+""));
}
Restaurant r = new Restaurant(foods);
for (int i = 0; i < 3; i++) {
new Thread(r).start();
}*/
List<Food> foods = new ArrayList<Food>();
for (int i = 0; i < 4; i++) {
new Thread(new Cook(foods),"Cook"+(i+1)).start();
}
for (int i = 0; i < 3; i++) {
new Thread(new SaleWindow(foods),"sale"+(i+1)).start();
}
}
}

线程中消费者生产者的实例代码(使用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. 学以致用三----centos7.2基本环境补充

    补充: 在上一篇里,加时间戳 echo ‘export HISTTIMEFORMAT ="%F %T `whoami`" ’ >> /etc/profile sourc ...

  2. font-style字体设置

    用到一些字体找起来很麻烦,扒了一些 未测试 HTML,CSS,font-family:中文字体的英文名称 宋体 SimSun黑体 SimHei微软雅黑 Microsoft YaHei微软正黑体 Mic ...

  3. AngularJS实战之filter的使用二

    博文一中的filter是angular自带的filter,一般不会满足我们的使用.我们可以自定义filter. 一.自定义filter实现反转字符串 <div>{{ceshi|revers ...

  4. ActiveMQ -5.9和jms-1.1源码下载

    ActiveMQ-5.9和jms-1.1源码下载:见附件

  5. git使用教程(初次配置+错误提示)

    初次使用配置目录:https://blog.csdn.net/Esc_Tab_End/article/details/84144063 error: RPC failed; curl 56 OpenS ...

  6. c语言洗牌算法

    #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> voi ...

  7. 20155326 实验四 Android程序设计实验报告

    20155326 实验四 Android程序设计实验报告 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局管理器的使用: 3. ...

  8. 杭电2133What day is it

    给你个日期 问是星期几        知道1 1 1是周1就行了 #include <iostream>#include <cstdio>using namespace std ...

  9. PB常用函数

    弹出窗口:messagebox() 基本写法:Messagebox('标题','内容') 完整写法: MessageBox ( '标题','内容',图标,按键,默认值) (1)其中标题与内容为要显示的 ...

  10. Sql Server中的表访问方式Table Scan, Index Scan, Index Seek

    1.oracle中的表访问方式 在oracle中有表访问方式的说法,访问表中的数据主要通过三种方式进行访问: 全表扫描(full table scan),直接访问数据页,查找满足条件的数据 通过row ...