资讯专栏INFORMATION COLUMN

Java™ 教程(Lock对象)

RobinQu / 1130人阅读

Lock对象

同步代码依赖于简单的可重入锁,这种锁易于使用,但有许多限制,java.util.concurrent.locks包支持更复杂的锁定语法,我们不会详细检查这个包,而是将重点放在其最基本的接口Lock上。

Lock对象的工作方式与同步代码使用的隐式锁定非常相似,与隐式锁一样,一次只有一个线程可以拥有一个Lock对象,Lock对象还通过其关联的Condition对象支持wait/notify机制。

Lock对象优于隐式锁的最大优点是它们能够退出获取锁的尝试,如果锁立即不可用或超时到期之前(如果指定),则tryLock方法退出,如果另一个线程在锁被获得之前发送中断,则lockInterruptibly方法将退出。

让我们使用Lock对象来解决我们在活性中看到的死锁问题,Alphonse和Gaston训练自己注意朋友什么时候要鞠躬。我们通过要求我们的Friend对象必须在继续执行bow之前获取两个参与者的锁来对此进行建模,以下是改进模型Safelock的源代码。为了演示这个语法的多功能性,我们假设Alphonse和Gaston如此迷恋他们新发现的安全鞠躬能力,他们不能停止相互鞠躬:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;

public class Safelock {
    static class Friend {
        private final String name;
        private final Lock lock = new ReentrantLock();

        public Friend(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }

        public boolean impendingBow(Friend bower) {
            Boolean myLock = false;
            Boolean yourLock = false;
            try {
                myLock = lock.tryLock();
                yourLock = bower.lock.tryLock();
            } finally {
                if (! (myLock && yourLock)) {
                    if (myLock) {
                        lock.unlock();
                    }
                    if (yourLock) {
                        bower.lock.unlock();
                    }
                }
            }
            return myLock && yourLock;
        }
            
        public void bow(Friend bower) {
            if (impendingBow(bower)) {
                try {
                    System.out.format("%s: %s has"
                        + " bowed to me!%n", 
                        this.name, bower.getName());
                    bower.bowBack(this);
                } finally {
                    lock.unlock();
                    bower.lock.unlock();
                }
            } else {
                System.out.format("%s: %s started"
                    + " to bow to me, but saw that"
                    + " I was already bowing to"
                    + " him.%n",
                    this.name, bower.getName());
            }
        }

        public void bowBack(Friend bower) {
            System.out.format("%s: %s has" +
                " bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    static class BowLoop implements Runnable {
        private Friend bower;
        private Friend bowee;

        public BowLoop(Friend bower, Friend bowee) {
            this.bower = bower;
            this.bowee = bowee;
        }
    
        public void run() {
            Random random = new Random();
            for (;;) {
                try {
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {}
                bowee.bow(bower);
            }
        }
    }
            

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new BowLoop(alphonse, gaston)).start();
        new Thread(new BowLoop(gaston, alphonse)).start();
    }
}
上一篇:高级并发对象 下一篇:执行器

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73045.html

相关文章

  • Java 8 并发教程:同步和锁

    摘要:在接下来的分钟,你将会学会如何通过同步关键字,锁和信号量来同步访问共享可变变量。所以在使用乐观锁时,你需要每次在访问任何共享可变变量之后都要检查锁,来确保读锁仍然有效。 原文:Java 8 Concurrency Tutorial: Synchronization and Locks译者:飞龙 协议:CC BY-NC-SA 4.0 欢迎阅读我的Java8并发教程的第二部分。这份指南将...

    wyk1184 评论0 收藏0
  • Java精讲:生产者-消费者

    摘要:创建一个阻塞队列生产者生产,目前总共有消费者消费,目前总共有原文链接更多教程 原文链接 更多教程 本文概要 生产者和消费者问题是线程模型中老生常谈的问题,也是面试中经常遇到的问题。光在Java中的实现方式多达数十种,更不用说加上其他语言的实现方式了。那么我们该如何学习呢? 本文会通过精讲wait()和notify()方法实现生产者-消费者模型,来学习生产者和消费者问题的原理。 目的...

    VPointer 评论0 收藏0
  • Java教程(高级并发对象

    高级并发对象 到目前为止,本课程重点关注从一开始就是Java平台一部分的低级别API,这些API适用于非常基础的任务,但更高级的任务需要更高级别的构建块,对于充分利用当今多处理器和多核系统的大规模并发应用程序尤其如此。 在本节中,我们将介绍Java平台5.0版中引入的一些高级并发功能,大多数这些功能都在新的java.util.concurrent包中实现,Java集合框架中还有新的并发数据结构。 ...

    xiaotianyi 评论0 收藏0
  • 并发学习笔记 (5)

    摘要:执行会重新将设置为,并且通知唤醒其中一个若有的话在方法中调用了函数而处于等待状态的线程。除此之外,我们需要记录同一个线程重复对一个锁对象加锁的次数。竞争失败的线程处于就绪状态,长期竞争失败的线程就会饥饿。 tutorials site Locks in java Locks (and other more advanced synchronization mechanisms...

    meteor199 评论0 收藏0

发表评论

0条评论

RobinQu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<