线程中消费者生产者的实例代码(使用Lock类)
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类)的更多相关文章
- 线程中消费者生产者的实例代码(synchronized关键字)
http://www.cnblogs.com/DreamDrive/p/6204665.html 这个是用Lock类实现的. 场景: 厨师类: import java.util.List; impo ...
- Java线程中的join使用实例
JDK中解释为 Waits for this thread to die. 等待本线程结束后,下一个线程才可以运行. 实例要求: 现在有T1.T2.T3三个线程,你怎样保证T2在T1执行完后执行,T3 ...
- Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统
理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...
- Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统
理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...
- 《Lua程序设计》9.2 管道(pipe)与过滤器(filter) 包含使用协同函数实现“生产者——消费者”问题的实例代码
一个关于协同程序的经典示例是“生产者-消费者”问题.这其中涉及到两个函数,一个函数不断地产生值(比如从一个文件中读取值),另一个则不断地消费这些值(比如将这些值写到另一个文件).通常,这两个函数大致是 ...
- 详解 HTML5 中的 WebSocket 及实例代码-做弹幕
原文链接:http://www.php.cn/html5-tutorial-363345.html
- java-多线程的练习----妖,等待唤醒,代码重构,lock到condition
1 需求 资源有姓名和性别. 两个线程, 一个负责给姓名和性别赋值, 一个负责获取姓名和性别的值. 要求1,运行一下,解决程序的 "妖"的问题. 要求2,实现正确数据的 ...
- Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)
1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...
- Java子线程中的异常处理(通用)
在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何正确捕获子线程中的异常,从而进行相 ...
随机推荐
- python模块:pickle
"""Create portable serialized representations of Python objects. See module copyreg f ...
- devexpress 的combobox怎样只能选择不能输入
我们知道listbox和combobox的区别就是listbox是下拉列表框,只能下拉,不支持在listbox中自定义输入,而combobox是textbox和listbox的合体,被称为组合框. c ...
- 安卓TP驱动开发
转自 blog.csdn.net/dddxxxx/article/details/54312415
- matlab画无向图,基于坐标的无向图联系作者
%函数名netplot %使用方法输入请help netplot %无返回值 %函数只能处理无向图 %作者:tiandsp %最后修改: function netplot(A,flag) %调用方法输 ...
- asp.net DataReader DataTable 使用反射给给实体赋值
asp.net 使用反射给给实体赋值 实体类继承此基类 using System.Reflection; using System.Data.SqlClient; using System.Data; ...
- Topcoder-SRM-#712-Div2
250-RepeatNumberCompare Problem Statement For any two positive integers x and k we can make a new nu ...
- silverlight 父窗体传值给ChildWindow
在网上找了许多列子,有的没有看懂,有的太麻烦. 现在有两种方法又简单又实用的,分享给大家! 第一种:使用构造函数传值 1.子页面新建一个构造函数 public ChildWindowTest(stri ...
- web-day1
第1章 WEB01-HTML篇 今日任务 网站信息页面案例 网站图片信息页面案例 网站友情链接页面案例 网站首页案例 网站注册页面案例 网站后台页面案例 教学导航 教学目标 了解什么是标记语言 了 ...
- android ActivityGroup接收不到onActivityResult
android 框架嵌套,用viewgroup是很好用的.首先实现一个框架的activity,可以继承ActivityGroup 将需要切换的界面,放到ViewGroup里面. 切换如下: Inten ...
- POJ 1191棋盘分割问题
棋盘分割问题 题目大意,将一个棋盘分割成k-1个矩形,每个矩形都对应一个权值,让所有的权值最小求分法 很像区间DP,但是也不能说就是 我们只要想好了一个怎么变成两个,剩下的就好了,但是怎么变,就是变化 ...