- 浏览: 119653 次
- 性别:
- 来自: 部落格
文章分类
最新评论
-
只是打工的:
这文章是百度来的吧,不写个引用出处吗??
堆和栈 -
skill_job:
“主键设计有个原则,就是主键不应具有任何实际意义.”奇怪了,这 ...
数据库主键设计原则 -
zhou363667565:
写的还不错.
线程池 -
happyxuzheng:
我个人觉得选择数据类型为字符串的主键并且主键存入的是由数字进行 ...
数据库主键设计原则 -
tongfan:
都罗列出来了 可以!
js刷新页面
一个简单的ReentrantLock的例子, 情景是几个朋友吃饭, 可是美味的汤只有一锅, 勺子只有一个. 这样一来, 难免就会有你抢我争的情况了. 但是, 如果有更美味的其他食物, 当然可以先转头去找其他的了. synchronized是无法做到这点的.
Lunch类, 包括勺子(ReentrantLock)和"舀"的动作, 当这帮朋友想要"舀"的时候, 就只能一个人动手, 其他人乖乖等着, 或者被叫去干其他事情
package concurrent.lunch;
import java.util.concurrent.locks.ReentrantLock;
public class Lunch {
private ReentrantLock scoop = new ReentrantLock();
public boolean dip() {
try {
scoop.lockInterruptibly();
} catch (InterruptedException e) {
Logger.log("Some one call me for better food ^^ ");
return false;
}
Logger.log("hah, I got the scoop");
try {
// suppose we need 5s to dip the soup
try {
Thread.sleep(5000);
} catch (InterruptedException i) {
Logger.log("someone rob my scoop, 55~~~ ");
return false;
}
Logger.log("I got delicious food ");
} finally {
scoop.unlock();
}
return true;
}
}
Buddy类, 嘴馋的家伙, 抢着要"舀"汤, 不过如果抢不到, 也可以干别的
package concurrent.lunch;
public class Buddy extends Thread {
private final Lunch lunch;
public Buddy(Lunch lunch, String name) {
this.lunch = lunch;
this.setName(name);
}
public void run() {
while (!lunch.dip()) {
Logger.log("I will wait for a while to dip, see if any other better...");
try {
Thread.sleep(100);
} catch (InterruptedException ignore) {}
}
}
}
Party类, 宴会开始了, 每个人都想去抢那个勺子, 抢不到的又实在等不耐烦的话就只好暴力解决(interrupt)
package concurrent.lunch;
public class Party {
public static void main(String[] args) throws Exception {
// here we have to share the Lunch instance
Lunch lunch = new Lunch();
// here we MUST share the Lunch instance
Buddy Tityz= new Buddy(lunch, "Tityz");
Buddy Michael = new Buddy(lunch, "Michael");
Buddy Yutting= new Buddy(lunch, "Yutting");
Tityz.start();
Thread.sleep(100); //make sure Tityz got it first
Michael.start();
Yutting.start();
Thread.sleep(1000);
// why still hanging? rob him
Tityz.interrupt();
// ask michael to other food
Michael.interrupt();
}
}
Logger:
package concurrent.lunch;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Logger {
private static final SimpleDateFormat df = new SimpleDateFormat("hh:mm:ss");
public static void log(String msg) {
System.out.println(df.format(new Date()) + " "
+ Thread.currentThread().getName() + ":\t" +msg );
}
}
好了, 开始宴会吧.
02:42:24 Tityz: hah, I got the scoop
02:42:25 Tityz: someone rob my scoop, 55~~~
02:42:25 Michael: Some one call me for better food ^^
02:42:25 Yutting: hah, I got the scoop
02:42:25 Michael: I will wait for a while to dip, see if any other better...
02:42:25 Tityz: I will wait for a while to dip, see if any other better...
02:42:30 Yutting: I got delicious food
02:42:30 Tityz: hah, I got the scoop
02:42:35 Tityz: I got delicious food
02:42:35 Michael: hah, I got the scoop
02:42:40 Michael: I got delicious food
结果显而易见, 首先是Tityz拿到勺子, 但是因为"舀"比较花时间, 其他人都只能等. 不过一段时间(1s)过去了, 其他人忍不住了, "抢"了他的勺子, 而Michael则被叫去做其他事情了. 得渔利者Yutting也. Yutting搞定后, Tityz再次抢到勺子(这里的次序是随机的), 这次没人打断他了, Michael则最后才喝到汤.
例子完了, 但是我们应该考虑到问题是, 这个锁定, 到底锁定的对象是什么? ReentrantLock.lock()没有参数, 不想synchronized(xx)可以指定被锁定的对象. 那么我们只能假设ReentrantLock.lock()维护了内部的对象. 显然, 如果我们new了好几个ReentrantLock实例并且每个线程分别持有一个, 那么这些线程最终获取的锁定的对象就不是同一个. 这就是上面例子的Party里共用一个ReentrantLock的原因.
当然, 共用的形式不一定就是通过直接传递ReentrantLock对象给某个线程, 也可以是在线程执行的方法去共用ReentrantLock, 自己发挥想象力吧
同时也说一下上面代码的缺点, 留意一下上面代码Lunch.dip()的方法签名, public boolean dip(), 是带有返回值的, 这样的做法可谓喜忧参半, 好的一面是, 如果失败了, 调用该方法的线程有机会进行其他事情的处理, 不利的一面是调用该方法的线程被逼要使用不断尝试的方式来处理, 增加了代码复杂度.
我们有一种解决上述问题的做法, 就是让调用的线程等待, 直到条件满足为止. 可以参考java.util.concurrent.locks.Condition类的使用例子.
转自:http://hi.baidu.com/iwishyou2/blog/item/4c6119296e929ff699250a8a.html
Lunch类, 包括勺子(ReentrantLock)和"舀"的动作, 当这帮朋友想要"舀"的时候, 就只能一个人动手, 其他人乖乖等着, 或者被叫去干其他事情
package concurrent.lunch;
import java.util.concurrent.locks.ReentrantLock;
public class Lunch {
private ReentrantLock scoop = new ReentrantLock();
public boolean dip() {
try {
scoop.lockInterruptibly();
} catch (InterruptedException e) {
Logger.log("Some one call me for better food ^^ ");
return false;
}
Logger.log("hah, I got the scoop");
try {
// suppose we need 5s to dip the soup
try {
Thread.sleep(5000);
} catch (InterruptedException i) {
Logger.log("someone rob my scoop, 55~~~ ");
return false;
}
Logger.log("I got delicious food ");
} finally {
scoop.unlock();
}
return true;
}
}
Buddy类, 嘴馋的家伙, 抢着要"舀"汤, 不过如果抢不到, 也可以干别的
package concurrent.lunch;
public class Buddy extends Thread {
private final Lunch lunch;
public Buddy(Lunch lunch, String name) {
this.lunch = lunch;
this.setName(name);
}
public void run() {
while (!lunch.dip()) {
Logger.log("I will wait for a while to dip, see if any other better...");
try {
Thread.sleep(100);
} catch (InterruptedException ignore) {}
}
}
}
Party类, 宴会开始了, 每个人都想去抢那个勺子, 抢不到的又实在等不耐烦的话就只好暴力解决(interrupt)
package concurrent.lunch;
public class Party {
public static void main(String[] args) throws Exception {
// here we have to share the Lunch instance
Lunch lunch = new Lunch();
// here we MUST share the Lunch instance
Buddy Tityz= new Buddy(lunch, "Tityz");
Buddy Michael = new Buddy(lunch, "Michael");
Buddy Yutting= new Buddy(lunch, "Yutting");
Tityz.start();
Thread.sleep(100); //make sure Tityz got it first
Michael.start();
Yutting.start();
Thread.sleep(1000);
// why still hanging? rob him
Tityz.interrupt();
// ask michael to other food
Michael.interrupt();
}
}
Logger:
package concurrent.lunch;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Logger {
private static final SimpleDateFormat df = new SimpleDateFormat("hh:mm:ss");
public static void log(String msg) {
System.out.println(df.format(new Date()) + " "
+ Thread.currentThread().getName() + ":\t" +msg );
}
}
好了, 开始宴会吧.
02:42:24 Tityz: hah, I got the scoop
02:42:25 Tityz: someone rob my scoop, 55~~~
02:42:25 Michael: Some one call me for better food ^^
02:42:25 Yutting: hah, I got the scoop
02:42:25 Michael: I will wait for a while to dip, see if any other better...
02:42:25 Tityz: I will wait for a while to dip, see if any other better...
02:42:30 Yutting: I got delicious food
02:42:30 Tityz: hah, I got the scoop
02:42:35 Tityz: I got delicious food
02:42:35 Michael: hah, I got the scoop
02:42:40 Michael: I got delicious food
结果显而易见, 首先是Tityz拿到勺子, 但是因为"舀"比较花时间, 其他人都只能等. 不过一段时间(1s)过去了, 其他人忍不住了, "抢"了他的勺子, 而Michael则被叫去做其他事情了. 得渔利者Yutting也. Yutting搞定后, Tityz再次抢到勺子(这里的次序是随机的), 这次没人打断他了, Michael则最后才喝到汤.
例子完了, 但是我们应该考虑到问题是, 这个锁定, 到底锁定的对象是什么? ReentrantLock.lock()没有参数, 不想synchronized(xx)可以指定被锁定的对象. 那么我们只能假设ReentrantLock.lock()维护了内部的对象. 显然, 如果我们new了好几个ReentrantLock实例并且每个线程分别持有一个, 那么这些线程最终获取的锁定的对象就不是同一个. 这就是上面例子的Party里共用一个ReentrantLock的原因.
当然, 共用的形式不一定就是通过直接传递ReentrantLock对象给某个线程, 也可以是在线程执行的方法去共用ReentrantLock, 自己发挥想象力吧
同时也说一下上面代码的缺点, 留意一下上面代码Lunch.dip()的方法签名, public boolean dip(), 是带有返回值的, 这样的做法可谓喜忧参半, 好的一面是, 如果失败了, 调用该方法的线程有机会进行其他事情的处理, 不利的一面是调用该方法的线程被逼要使用不断尝试的方式来处理, 增加了代码复杂度.
我们有一种解决上述问题的做法, 就是让调用的线程等待, 直到条件满足为止. 可以参考java.util.concurrent.locks.Condition类的使用例子.
转自:http://hi.baidu.com/iwishyou2/blog/item/4c6119296e929ff699250a8a.html
发表评论
-
CDN技术关键点
2013-10-10 14:48 807如何用BIND, GeoIP, Nginx, Varnish来 ... -
Nginx安装
2013-03-21 18:22 0Nginx作为一个后起之秀,他的迷人之处已经让很多人都投入了他 ... -
weblogic初学习
2011-12-08 09:52 1265BEA WebLogic是用于开发、集成、部署和管理大型分布式 ... -
Spring 依赖注入详解
2011-11-28 21:13 649简介: Spring 的依赖配 ... -
CentOs IP NDS的设置
2011-11-27 20:30 1285【学习如何修改centos的IP地址、DNS以及网关】 一、 ... -
反射器模式
2011-11-09 10:16 916Java NIO非堵塞应用通常 ... -
linux ,VI命令编辑器
2011-11-06 23:14 1042本章介绍Linux上最常用 ... -
堆和栈
2011-11-01 16:02 1592Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/F ... -
超时任务
2011-10-31 09:04 1064import java.util.concurrent.Cal ... -
BlockingQueue使用
2011-10-29 10:40 1510import java.util.concurrent.Arr ... -
线程池
2011-10-24 16:55 3167在什么情况下使用线程池? 1.单个任务处理的时间比 ... -
异步执行线程并可以得到返回值
2011-10-24 16:33 8850import java.util.concurrent.Cal ... -
Oracle rowid 优化分页
2011-10-18 16:15 1424今天看到一个分享,了解到DBA对oracle的分页方法进行优化 ... -
dmp命令导数据库
2011-10-15 22:24 840导出:exp usename/password@SID fil ... -
Struts2.0
2011-08-30 13:48 729struts.properties文件,该文 ... -
全面整合spring管理struts,spring管理hibernate
2011-08-30 13:37 1046黄金组合之全面整合,让spring管理struts,sprin ... -
BoneCp的设置
2011-03-29 08:24 1389一、BoneCP配置文件格式(bonecp-config.xm ... -
tomcat工程部署记录
2011-03-17 16:11 955第一种方法:在tomcat中的conf目录中,在server. ... -
Spring + Hibernate 配置BoneCp
2011-03-15 21:34 2468为什么 BoneCP 连接池的性能这么高呢?(bonecp-0 ... -
Spring的加入记录
2011-03-15 21:09 788在J2EE的web应用里面配置spring非常简单,最简单的只 ...
相关推荐
第15讲丨synchronized和ReentrantLock有什么区别呢?.html
在 Java 5 以前,synchronized 是仅有的同步手段,在代码中, synchronized 可以用来修饰方法,也可以使用在特定的代码块儿上,本质上
ReentrantLock java除了使用关键字synchronized外,还可以使用ReentrantLock实现独占锁的功能。而且ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。这篇文章主要是从...
java语言 并发编程 ReentrantLock与synchronized区别 详解
ReentrantLock的使用及注意事项
1、ReentrantLock简介 2、ReentrantLock函数列表 3、重入的实现 4、公平锁与非公平锁 5、ReentrantLock 扩展的功能 6
ReentrantLock源码剖析
我是一名很普通的双非大三学生。接下来的几个月内,我将坚持写博客,输出知识的同时巩固自己的基础,记录自己的...在Java中每个对象都隐式包含一个monitor (监视器)对象,加锁的过程其实就是竞争monitor的过程,当线
一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个...
这份资源旨在详细讲解 Java 中的 Locks 框架,特别关注 ReentrantLock 的使用和原理。Locks 框架提供了比传统的 synchronized 关键字更强大、更灵活的线程同步机制,而 ReentrantLock 是其中的一种重要实现。 Locks ...
腾讯面试题 你了解ReentrantLock吗? ReetrantLock是一个可重入的独占锁,主要有两个特性,一个是支持公平锁和非公平锁,一个是可重入。 ReetrantLock实现依赖于AQS(AbstractQueuedSynchronizer)(不懂得话可以看我上...
ReentrantLock 实现原理 1
ReentrantLock lock方法注释
1. ReentrantLock的介绍 ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java...
助于理解的例子 博文链接:https://uule.iteye.com/blog/1488356
NULL 博文链接:https://patrick002.iteye.com/blog/2170391
ReentrantLock类可以唤醒指定条件的线程,而object的唤醒是随机的 Condition类和Object类 Condition类的awiat方法和Object类的wait方法等效 Condition类的signal方法和Object类的notify方法等效 Condition类...
近日,阅读jdk并发包源码分析整理笔记。
什么是公平锁和非公平锁 公平与非公平的一个很本质的区别就是,是否遵守FIFO(也就是先来后到)。当有多个线程来申请锁的时候,是否先申请的线程先获取锁,后申请的线程后获取锁?如果是的,则是 公平锁 ,否则是...
ReentrantLock.java