- 浏览: 258306 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (289)
- java (72)
- oracle (3)
- mysql (5)
- spring (28)
- hibernate (2)
- osgi (0)
- linux (2)
- ExtJs (1)
- jvm (0)
- mybatis (7)
- 分布式 (11)
- MINA (6)
- apache+tomcat (13)
- js+htm (7)
- android (44)
- http (1)
- hbase+hdoop (0)
- memcache (13)
- search (27)
- 部署及性能 (12)
- mongoDB (2)
- 多线程 (12)
- 安全管理验证 (9)
- struts (1)
- webservice (0)
- easyUI (1)
- spring security (16)
- pattern (6)
- 算法 (2)
最新评论
-
lzh8189146:
CommonsHttpSolrServer这个类,现在是不是没 ...
CommonsHttpSolrServer -
xiaochanzi:
我按照你的方法试了下,tomcat6可以发布,但是访问任何网页 ...
基于内嵌Tomcat的应用开发 -
phoneeye:
麻烦你,如果是抄来的文章,请给出来源。谢谢
ant 两则技巧 -
neverforget:
转载不注明出处
Spring Security3.1登陆验证 替换 usernamepasswordfilter -
liang1022:
若不使用eclipse ,如何在命令行下 运行服务端程序 ?
WebService CXF学习(入门篇2):HelloWorld
一个简单的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类的使用例子.
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类的使用例子.
发表评论
-
Java keytool 安全证书学习笔记
2012-08-02 14:16 795http://linliangyi2007.iteye.com ... -
java国际化
2012-07-16 14:08 409http://lavasoft.blog.51cto.com/ ... -
Java版远程控制V1.0
2012-06-17 21:37 749http://www.cnblogs.com/syxchina ... -
浅析Java中CountDownLatch用法
2012-05-16 20:57 791CountDownLatch如其所写,是一个 ... -
SMTP发送邮件
2012-04-18 09:41 756SMTP发送邮件 openkk 2011-06-0 ... -
smtp 返回代码 信息
2012-04-18 08:52 1440SMTP Server Response Cod ... -
JavaMail详解
2012-04-18 02:24 0JavaMail详解 博客分类: JAV ... -
安装Eclipse反编译插件
2012-04-17 09:34 798安装Eclipse反编译插件 博客分类: ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-04-13 08:30 659最近的机器内存又爆满了,除了新增机器内存外,还应该好好r ... -
Dijkstra算法
2012-04-11 08:00 859Dijkstra算法 博客分类: 算 ... -
java 播放音乐
2012-04-11 08:00 993java 播放音乐 博客分类: J2 ... -
Java中的native,transient,volatile和strictfp关键字
2012-04-06 08:49 727Java中的native,transient,v ... -
Hashmap 分析
2012-04-05 08:32 725Hashmap 博客分类: 算法 ... -
多线程摘录 004
2012-04-05 08:32 750* 使用哪种模式的并发?观察一下简单的服务器方式一: ... -
ExecutorService线程池
2012-04-05 08:32 752ExecutorService线程池 (2010 ... -
Java并发:juc Executor框架详解
2012-04-05 08:32 774Java并发:juc Executor ... -
java并发包,多线程,工具类,笔记
2012-04-11 08:00 891JDK 线程池 Executors.newCachedT ... -
利用 Spring 和 EHCache 做方法缓存处理〔转〕
2012-04-09 09:49 834利用 Spring 和 EHCache 做方法缓存处理〔 ... -
EhCache使用详细介绍
2012-04-09 09:49 1344EhCache使用详细介绍 Ehcache中不仅可 ... -
HashMap 分析
2012-04-01 08:21 1894http://www.blogjava.net ...
相关推荐
ReentrantLock的lock方法使用CAS操作来尝试更新对象内的一个变量,如果更新成功,则将exclusiveOwnerThread变量设置为当前线程,然后lock方法会立刻返回。如果更新不成功,则调用acquire(1)方法。 ReentrantLock的...
Lock、Synchronized 和 ReentrantLock 的使用 Lock、Synchronized 和 ReentrantLock 是 Java 中三种常用的同步机制,每种机制都有其特点和使用场景。下面对这三种机制进行详细的分析和比较。 一、Synchronized ...
ReentrantLock的使用及注意事项
Java中的ReentrantLock是线程安全编程中的一种高级锁机制,它属于Lock接口的一个实现,提供了比synchronized更丰富的功能和更高的灵活性。ReentrantLock的名字来源于它的可重入性,这意味着一个线程可以多次获取同一...
`ReentrantLock`是Java并发编程中的一种高级锁机制,它是`java.util.concurrent.locks`包中的类,提供了比`...了解并熟练使用`ReentrantLock`能帮助开发者更好地解决并发问题,提高程序的并发性能和健壮性。
用CyclicBarrier,reentrantlock,condition来完成同时购买,同步购买的功能 JUC系列之模拟抢票(N人同时抢票,票不足系统补仓,N-M人继续抢票) http://blog.csdn.net/crazyzxljing0621/article/details/77891620
《ReentrantLock源码详解与应用》 ReentrantLock,可重入锁,是Java并发编程中一个重要的锁实现,它提供了比synchronized更高级别的控制能力,包括公平性和非公平性选择。本文将深入探讨ReentrantLock的原理,特别...
《ReentrantLock深度解析》 在Java并发编程中,ReentrantLock是JDK提供的一个可...在实际开发中,可以根据需求选择使用synchronized还是ReentrantLock,或者其他的并发控制手段,以达到最佳的并发性能和资源利用效率。
本篇文章将深入探讨`ReentrantLock`的使用以及如何结合Lambda表达式来优化同步代码。 `ReentrantLock`是Java并发包`java.util.concurrent.locks`中的一个类,它是可重入的互斥锁,具备与`synchronized`相同的基本...
java语言 并发编程 ReentrantLock与synchronized区别 详解
在Java多线程编程中,`ReentrantLock`和`synchronized`都是用于实现线程同步的重要工具,确保在并发环境中数据的一致性和正确性。两者虽然都能实现互斥访问,但在功能、性能以及使用场景上有所不同。下面我们将深入...
### ReentrantLock源码分析 #### 一、ReentrantLock简介 ReentrantLock是一个基于`AbstractQueuedSynchronizer`(AQS)实现的高级锁工具类。与传统的synchronized关键字相比,ReentrantLock提供了更多控制手段,比如...
本篇文章将深入探讨`ReentrantLock`的特性,功能以及如何使用。 ### 1. ReentrantLock简介 `ReentrantLock`是Java并发编程中的一种重要工具,它允许线程在已经获取锁的情况下再次获得同一把锁,而不必等待解锁。这...
默认情况下,ReentrantLock 使用非公平锁,它的效率和吞吐量都比公fair锁高的多。 获取锁的过程中,ReentrantLock 使用了 AQS 的 acquiring 机制。首先,ReentrantLock 会调用 sync 的 lock 方法,而这个方法是一个...
一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个...
在Java并发编程中,理解和熟练使用同步机制是至关重要的,这包括了`ReentrantLock`和`synchronized`关键字。这两个工具都是为了确保多线程环境中的数据一致性与安全性,防止出现竞态条件和死锁等问题。 `...
默认情况下,`ReentrantLock`使用的是非公平锁,因为非公平锁在大多数情况下具有更高的吞吐量。 `Sync`类继承自`AbstractQueuedSynchronizer`(AQS),这是一个非常关键的抽象类,它提供了锁和其他同步组件的基础框架...
- 使用`ReentrantLock`时,必须显式地在`finally`块中释放锁,以防止由于异常而导致的锁未释放问题。 - `ReentrantLock`支持重入特性,即允许同一个线程多次获取同一把锁,这与`synchronized`的行为一致。 #### ...
ReentrantLock lock方法注释
ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java关键字synchronized隐式支持重...