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. 软件推荐-国内参数优化软件:1stOpt - First Optimizationg

    首页:http://www.7d-soft.com/index.htm 4.0新功能 (预定2010年8月6日): 1:支持复数拟合.复数方程组计算: 2:支持微分方程拟合求解: 3:通用全局优化求解 ...

  2. IntelliJ IDEA 2017版 spring-boot 拦截器的操作三种方式

    一.注解方式 @WebServlet(urlPatterns = "/myServlet") public class MyServlet extends HttpServlet ...

  3. laravel 5.1 使用Eloquent ORM 操作实例

    Laravel 的 Eloquent ORM 提供了更优雅的ActiveRecord 实现来和数据库的互动. 每个数据库表对应一个模型文件. 数据库配置 .env文件(也可以直接修改config/da ...

  4. 阿里云oss如何上传一个文件夹

    最近公司在做工程项目,实现文件夹云存储上传 网上找了很久,发现很多项目都存在一些问题,但还是让我找到了一个成熟的项目. 工程: 对项目的文件夹云存储上传功能做出分析,找出文件夹上传的原理,对文件夹的云 ...

  5. java的静态内部类

    只是一个简单的记录.因为一直排斥java这个东西.java跟c++比是很不错的一个语言,至少内存管理这么麻烦的东西不用操心了.但是和不断崛起的脚本语言比起来,效率差的太多.无论如何做android还是 ...

  6. Write Markdown Syntax Online Document with Sphinx and Pandoc

    There is no doubt that we have to write doc while we are developing software. But How do you write d ...

  7. 修改Android EditText光标颜色

    EditText有一个属性:android:textCursorDrawable,这个属性是用来控制光标颜色的   android:textCursorDrawable="@null&quo ...

  8. Python3 安装 PyQt5 -pycharm 环境搭建

    执行命令: pip3 install PyQt5 PyQt5+python3+pycharm开发环境配置   1.下载PyQt 官方网站:http://www.riverbankcomputing.c ...

  9. unigui的编译部署

    unigui的编译部署 unigui既可以EXE形态部署,也可以IIS的ISAPI的形态部署.关键在工程文件.dpr里面的编译开关. {$define UNIGUI_VCL} // 注释此编译开关将使 ...

  10. Delphi获取公网IP地址函数

    uses IdHTTP; function GetPublicIP: string; var strIP, URL: string; iStart, iEnd: Integer; MyIdHTTP: ...