- 浏览: 123572 次
- 性别:
- 来自: 部落格
文章分类
最新评论
-
只是打工的:
这文章是百度来的吧,不写个引用出处吗??
堆和栈 -
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 849如何用BIND, GeoIP, Nginx, Varnish来 ... -
Nginx安装
2013-03-21 18:22 0Nginx作为一个后起之秀,他的迷人之处已经让很多人都投入了他 ... -
weblogic初学习
2011-12-08 09:52 1323BEA WebLogic是用于开发、集成、部署和管理大型分布式 ... -
Spring 依赖注入详解
2011-11-28 21:13 741简介: Spring 的依赖配 ... -
CentOs IP NDS的设置
2011-11-27 20:30 1359【学习如何修改centos的IP地址、DNS以及网关】 一、 ... -
反射器模式
2011-11-09 10:16 969Java NIO非堵塞应用通常 ... -
linux ,VI命令编辑器
2011-11-06 23:14 1128本章介绍Linux上最常用 ... -
堆和栈
2011-11-01 16:02 1702Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/F ... -
超时任务
2011-10-31 09:04 1148import java.util.concurrent.Cal ... -
BlockingQueue使用
2011-10-29 10:40 1570import java.util.concurrent.Arr ... -
线程池
2011-10-24 16:55 3215在什么情况下使用线程池? 1.单个任务处理的时间比 ... -
异步执行线程并可以得到返回值
2011-10-24 16:33 8916import java.util.concurrent.Cal ... -
Oracle rowid 优化分页
2011-10-18 16:15 1504今天看到一个分享,了解到DBA对oracle的分页方法进行优化 ... -
dmp命令导数据库
2011-10-15 22:24 891导出:exp usename/password@SID fil ... -
Struts2.0
2011-08-30 13:48 779struts.properties文件,该文 ... -
全面整合spring管理struts,spring管理hibernate
2011-08-30 13:37 1090黄金组合之全面整合,让spring管理struts,sprin ... -
BoneCp的设置
2011-03-29 08:24 1454一、BoneCP配置文件格式(bonecp-config.xm ... -
tomcat工程部署记录
2011-03-17 16:11 999第一种方法:在tomcat中的conf目录中,在server. ... -
Spring + Hibernate 配置BoneCp
2011-03-15 21:34 2516为什么 BoneCP 连接池的性能这么高呢?(bonecp-0 ... -
Spring的加入记录
2011-03-15 21:09 830在J2EE的web应用里面配置spring非常简单,最简单的只 ...
相关推荐
- 修饰代码块:可以指定锁定的对象,通常用于同步类中的非静态成员变量。 3. **优势**: - 使用简单,无需额外的API依赖。 - 自动释放锁,当线程执行完同步代码块或方法后,会自动释放锁。 4. **局限性**: - ...
Synchronized 的实现是基于锁机制的,它会锁定一个对象的监视器,以便防止其他线程访问该对象。Synchronized 的优点是易于使用和理解,编译器通常会对其进行优化,可以提高性能。然而,Synchronized 也有一些缺点,...
`synchronized`是Java内置的原生锁,它提供了对方法或代码块的锁定,使得在任何时刻只有一个线程能够执行特定的代码。synchronized有以下特性: 1. **互斥性**:当一个线程进入一个由synchronized修饰的方法或代码...
首先,对象锁是针对对象级别的锁定,它保护的是实例方法或者一个特定的代码块。当一个线程进入一个由`synchronized`修饰的实例方法或代码块时,它会获取到该对象的锁,其他试图访问同一锁的线程将被阻塞,直到持有锁...
* 使用ReentrantLock时,JVM不能包括锁定信息在线程转储中,对调试不太友好。 Condition是ReentrantLock的一个伴随类,提供了对线程的等待和唤醒等操作。Condition对象可以通过Lock对象的newCondition()方法创建,...
- 使用`ReentrantLock`的`newCondition()`方法创建`Condition`对象,然后使用`await()`和`signal()`方法实现线程间的等待和通知。 5. **死锁** - **题1**:什么是死锁? - 死锁发生在两个或多个线程互相等待对方...
通过这个指针,虚拟机能够识别对象属于哪个类的实例。 对于数组对象,除了上述两部分外,还有一个额外的长度字段,用于记录数组的长度。 为了查看Java对象的实际内存布局,可以利用如OpenJDK的JOL(Java Object ...
在Java中,每个对象都有一个隐含的`monitor`(监视器)对象,线程通过`monitorenter`和`monitorexit`指令来获取和释放锁。当线程试图进入一个已锁定的监视器时,它会被阻塞,直到持有锁的线程释放锁。这种机制确保了...
本文将深入探讨Java多线程同步的核心概念,特别是`synchronized`关键字的使用,以及锁定对象与锁定类的区别。 1. **线程安全问题** 在多线程环境中,当多个线程同时访问和修改同一份共享资源时,如果没有合适的...
但不同的对象就像不同的厕所,线程A锁定对象A不会影响线程B锁定对象B,即使两个对象的锁都释放了,线程之间也不会发生交错,因为它们各自独立。 除了`synchronized`,Java还提供了其他并发控制工具,如`java.util....
- **ReentrantLock**:提供比synchronized更高级别的锁定机制,支持更细粒度的锁控制,例如可中断的锁、可定时的锁等。 #### 五、JVM与性能优化 **1. JVM的主要组成部分有哪些?** - **类加载器(ClassLoader)**...
│ 06 可重入锁ReentrantLock的锁定原理.mp4 │ 07 可重入锁ReentrantLock之公平锁.mp4 │ 08 对象条件1.mp4 │ 09 对象条件2.mp4 │ 10 条件对象的注意事项.mp4 │ 11 等待唤醒机制的基本概念.mp4 │ 12 等待...
│ 06 可重入锁ReentrantLock的锁定原理.mp4 │ 07 可重入锁ReentrantLock之公平锁.mp4 │ 08 对象条件1.mp4 │ 09 对象条件2.mp4 │ 10 条件对象的注意事项.mp4 │ 11 等待唤醒机制的基本概念.mp4 │ 12 等待...
│ 06 可重入锁ReentrantLock的锁定原理.mp4 │ 07 可重入锁ReentrantLock之公平锁.mp4 │ 08 对象条件1.mp4 │ 09 对象条件2.mp4 │ 10 条件对象的注意事项.mp4 │ 11 等待唤醒机制的基本概念.mp4 │ 12 等待...
│ 06 可重入锁ReentrantLock的锁定原理.mp4 │ 07 可重入锁ReentrantLock之公平锁.mp4 │ 08 对象条件1.mp4 │ 09 对象条件2.mp4 │ 10 条件对象的注意事项.mp4 │ 11 等待唤醒机制的基本概念.mp4 │ 12 等待...
* synchronized是Java内置关键字,在JVM层面上锁定对象,而Lock是Java类。 * synchronized可以给类、方法、代码块加锁,而Lock只能给代码块加锁。 * synchronized不需要手动获取锁和释放锁,而Lock需要手动加锁和...
以上内容涵盖了Java中高并发和多线程面试可能遇到的问题,包括Synchronized关键字的使用、原理、锁定对象、可重入性、JVM对锁的优化、Synchronized的公平性和非公平性、以及锁消除和锁粗化的概念。掌握这些知识点...
### 2011最新Java程序员面试笔试宝典 ...方法时,它是否锁定该对象? 当一个线程进入一个对象的一个`synchronized`方法时,它会锁定该对象,确保其他线程不能同时进入该对象的其他`synchronized`方法。
- 对于引用数据类型:比较的是对象在内存中的地址是否相同(即是否指向同一个对象)。 - **equals()**: 通常用于比较两个对象的内容是否相同,需要由子类重写该方法来定义具体的比较逻辑。 **3. 两个对象的`...
条件对象是与`ReentrantLock`关联的概念,它们允许线程在满足特定条件之前等待,而不是一直保持锁定状态。在银行转账的例子中,如果账户余额不足,线程不应该继续执行转账操作,而是应该等待账户有足够的资金。使用...