java reentrantlock 翻译用在什么地方

ReentrantLock有什么用处? - ITeye问答
如题所述,发现调用 ReentrantLock.lock()方法时候并不能造成死锁。
问题补充:Rainbow702 写道官方:
一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。
它提供了lock()方法:
如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
如果当前线程已经保持该锁定,则将保持计数加 1,并且该方法立即返回。
如果该锁定被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁定之前,该线程将一直处于休眠状态,此时锁定保持计数被设置为 1。
按照官方的解释,如果线程A调用了lock方法,线程B调用lock方法时候应该是被禁用的,实际上线程B并没有在调用lock方法时候死锁!
以下是测试代码
package net.kaixindog.
import java.util.concurrent.locks.ReentrantL
public class T extends Thread{
public final ReentrantLock lock=new ReentrantLock();
private int threadId;
public T(int threadId){
this.threadId=threadId;
public void run(){
lock.lock();
System.out.println("Thread ["+threadId+"]lock!");
System.out.println("Thread ["+threadId+"]unlock!");
System.out.println("Thread ["+threadId+"]"+lock.isHeldByCurrentThread());
lock.unlock();
/* public void run(){
synchronized(lock){
System.out.println("Thread ["+threadId+"]lock!");
System.out.println("Thread ["+threadId+"]unlock!");
package net.kaixindog.
* net.kaixindog.test
* @author lixm
* description:
public class ReentrantLockTest {
* @param args
public static void main(String[] args) {
// TODO Auto-generated method stub
T t1=new T(1);
T t2=new T(2);
T t3=new T(3);
t1.start();
t2.start();
t3.start();
采纳的答案
你每个线程都有自己的Lock,当然不行了
需要3个线程用一个Lock
你多个线程都是用了各自的lock当然不行了,你把lock改成static吧。
& 兄弟是这样的,锁的概念是针对多个线程访问一个对象产生的,也就是说比如现在有个类
class Test{
public void mytest(){
System.out.println("test");
& 然后呢 有两个线程对象 ThreadA和ThreadB来访问这个Test对象test的mytest()方法。我们假设不加锁的状况,此时线程ThreadA和ThreadB会都去执行mytest。假如mytest里面的逻辑更加复杂 甚至有一些改变数据的操作,那么此时是危险的,这个时候就有了锁的必要性。然后咱们改动Test方法。
&&
class Test{
public final ReentrantLock lock=new ReentrantLock();
public void mytest(){
lock.lock();
System.out.println("Thread
["+Thread.currentThread().getName()+"]!");
lock.unlock();
给它加把锁 ,现在你再执行ThreadA和ThreadB,会发现每次只能一个线程进去,也就是说锁起了作用。
你上面的代码 每个线程执行的是自己的run方法 出不了效果也就在情理之中了。
对的,ymmihw 和 freish 的解答请你看一下,应该像这样实现才是OK的
public static final ReentrantLock lock=new ReentrantLock();& 试试
官方:
一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。
它提供了lock()方法:
如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
如果当前线程已经保持该锁定,则将保持计数加 1,并且该方法立即返回。
如果该锁定被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁定之前,该线程将一直处于休眠状态,此时锁定保持计数被设置为 1。
已解决问题
未解决问题后使用快捷导航没有帐号?
查看: 559|回复: 8
Condition和ReentrantLock这样的组合的适用场景是什么
金牌会员, 积分 2490, 距离下一级还需 510 积分
论坛徽章:17
Condition和ReentrantLock这样的组合的适用场景是什么?
大家可以探讨一下,JDK里面用到了基于Array实现的BlockingQueue上面,用来实现生产者和消费者的模型
那是不是可以归纳为需要对同一个资源进行不同条件的判断的情况可以用这个组合?
这样起到的作用是两个目的:1.互斥的访问同一资源& &2.实现不同条件的判断
但是对于生产者和消费者问题,是不是用信号量+锁的方式更直观一些?
中级会员, 积分 291, 距离下一级还需 209 积分
论坛徽章:7
应该是的吧 求其他大神回答一下
注册会员, 积分 125, 距离下一级还需 75 积分
论坛徽章:2
个人感觉除非真的有必要使用新的场景,否则不建议使用
注册会员, 积分 125, 距离下一级还需 75 积分
论坛徽章:2
个人感觉除非真的有必要使用新的特性,不建议使用
金牌会员, 积分 1620, 距离下一级还需 1380 积分
论坛徽章:7
其实就是wait/notify/notifyAll和synchronized的面向对象编程升级版,之前JDK5的并发包没出来前都是使用wait/notify/notifyAll和synchronized编写基于锁的并发代码,后来JDK5并发包出来后,wait/notify/notifyAll都可以使用Condition替代,而synchronized可以使用ReentrantLock替代
注册会员, 积分 78, 距离下一级还需 122 积分
论坛徽章:2
只是不要忘胃释放锁就行了。
金牌会员, 积分 2490, 距离下一级还需 510 积分
论坛徽章:17
其实就是wait/notify/notifyAll和synchronized的面向对象编程升级版,之前JDK5的并发包没出来前都是使用wai ...
感觉还是有些差异的,ReentrantLock和Condition需要组合起来用,但是wait\notify和Synchronized就没有这样的要求了,通常是独立解决一类问题
金牌会员, 积分 1620, 距离下一级还需 1380 积分
论坛徽章:7
本帖最后由 whg 于
20:30 编辑
感觉还是有些差异的,ReentrantLock和Condition需要组合起来用,但是wait\notify和Synchronized就没有这 ...
Synchronized单独可以,但是使用wait\notify必须和Synchronized组合起呀,你用wait\notify不先Synchronized是不行的。。。就好比ReentrantLock可以单独使用,但是Condition必须和ReentrantLock关联一起,因为Condition是从ReentrantLock身上衍生出来的
差异只是写法上的差异而已,效果是等同的,上面我就说了:就是JDK5并发包想以面相对象的写法替换掉老式并发锁编程的写法,更灵活可控而已,并发包很多并发结构都基于ReentrantLock和Condition写的
金牌会员, 积分 2490, 距离下一级还需 510 积分
论坛徽章:17
Synchronized单独可以,但是使用wait\notify必须和Synchronized组合起呀,你用wait\notify不先Synchroniz ...
明白了,还是工作中用的太少,理解不透彻
扫一扫加入本版微信群java并发控制:ReentrantLock Condition使用详解 - 为程序员服务
为程序员服务
java并发控制:ReentrantLock Condition使用详解
java的java.util.concurrent.locks包内有Condition接口,该接口的官方定义如下:
Condition factors out the Object monitor methods (,
and ) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary
implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.
Conditions (also known as condition queues or condition variables) provide a means for one thread to suspend execution (to "wait") until notified by another thread that some state condition may now be true. Because access to this shared state information occurs in different threads, it must be protected, so a lock of some form is associated with the condition. The key property that waiting for a condition provides is that it atomically releases the associated lock and suspends the current thread, just like Object.wait.
我们通过一个实际的例子来解释Condition的用法:
我们要打印1到9这9个数字,由A线程先打印1,2,3,然后由B线程打印4,5,6,然后再由A线程打印7,8,9. 这道题有很多种解法,现在我们使用Condition来做这道题(使用Object的wait,notify方法的解法在)。
package cn.outofmemory.
import java.util.concurrent.locks.C
import java.util.concurrent.locks.L
import java.util.concurrent.locks.ReentrantL
public class App {
static class NumberWrapper {
public int value = 1;
public static void main(String[] args) {
//初始化可重入锁
final Lock lock = new ReentrantLock();
//第一个条件当屏幕上输出到3
final Condition reachThreeCondition = lock.newCondition();
//第二个条件当屏幕上输出到6
final Condition reachSixCondition = lock.newCondition();
//NumberWrapper只是为了封装一个数字,一边可以将数字对象共享,并可以设置为final
//注意这里不要用Integer, Integer 是不可变对象
final NumberWrapper num = new NumberWrapper();
//初始化A线程
Thread threadA = new Thread(new Runnable() {
public void run() {
//需要先获得锁
lock.lock();
System.out.println("threadA start write");
//A线程先输出前3个数
while (num.value &= 3) {
System.out.println(num.value);
num.value++;
//输出到3时要signal,告诉B线程可以开始了
reachThreeCondition.signal();
} finally {
lock.unlock();
lock.lock();
//等待输出6的条件
reachSixCondition.await();
System.out.println("threadA start write");
//输出剩余数字
while (num.value &= 9) {
System.out.println(num.value);
num.value++;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
Thread threadB = new Thread(new Runnable() {
public void run() {
lock.lock();
while (num.value &= 3) {
//等待3输出完毕的信号
reachThreeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
lock.lock();
//已经收到信号,开始输出4,5,6
System.out.println("threadB start write");
while (num.value &= 6) {
System.out.println(num.value);
num.value++;
//4,5,6输出完毕,告诉A线程6输出完了
reachSixCondition.signal();
} finally {
lock.unlock();
//启动两个线程
threadB.start();
threadA.start();
上述代码中有完整的注释,请参考注释,理解Condition的用法。
基本思路就是首先要A线程先写1,2,3,这时候B线程应该等待reachThredCondition信号,而当A线程写完3之后就通过signal告诉B线程“我写到3了,该你了”,这时候A线程要等嗲reachSixCondition信号,同时B线程得到通知,开始写4,5,6,写完4,5,6之后B线程通知A线程reachSixCondition条件成立了,这时候A线程就开始写剩下的7,8,9了。
为了更好的理解Condition的用法,我们再看下java官方提供的例子:
import java.util.R
import java.util.concurrent.locks.C
import java.util.concurrent.locks.L
import java.util.concurrent.locks.ReentrantL
public class AppOfficial {
* BoundedBuffer 是一个定长100的集合,当集合中没有元素时,take方法需要等待,直到有元素时才返回元素
* 当其中的元素数达到最大值时,要等待直到元素被take之后才执行put的操作
* @author yukaizhao
static class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr,
public void put(Object x) throws InterruptedException {
System .out.println("put wait lock");
lock.lock();
System.out.println("put get lock");
while (count == items.length) {
System.out.println("buffer full, please wait");
notFull.await();
items[putptr] =
if (++putptr == items.length)
putptr = 0;
notEmpty.signal();
} finally {
lock.unlock();
public Object take() throws InterruptedException {
System.out.println("take wait lock");
lock.lock();
System.out.println("take get lock");
while (count == 0) {
System.out.println("no elements, please wait");
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
notFull.signal();
} finally {
lock.unlock();
public static void main(String[] args) {
final BoundedBuffer boundedBuffer = new BoundedBuffer();
Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("t1 run");
for (int i=0;i&1000;i++) {
System.out.println("putting..");
boundedBuffer.put(Integer.valueOf(i));
} catch (InterruptedException e) {
e.printStackTrace();
Thread t2 = new Thread(new Runnable() {
public void run() {
for (int i=0;i&1000;i++) {
Object val = boundedBuffer.take();
System.out.println(val);
} catch (InterruptedException e) {
e.printStackTrace();
t1.start();
t2.start();
这个示例中BoundedBuffer是一个固定长度的集合,这个在其put操作时,如果发现长度已经达到最大长度,那么会等待notFull信号,如果得到notFull信号会像集合中添加元素,并发出notEmpty的信号,而在其take方法中如果发现集合长度为空,那么会等待notEmpty的信号,同时如果拿到一个元素,那么会发出notFull的信号。
推荐阅读:
相关聚客文章}

我要回帖

更多关于 reentrantlock 公平锁 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信