zoukankan      html  css  js  c++  java
  • Java Concurrency

    Lock 是 Java API 提供的另一种线程同步机制,它提供了比 synchronized 关键字更为灵活、强大的锁定操作。

    锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问,一次只允许一个线程获得锁,对共享资源的所有访问都需要先获得锁。不过,某些锁可能允许对共享资源并发访问,如 ReadWriteLock 的读锁。

    synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。

    虽然 synchronized 方法和语句的范围机制使得使用监视器锁编程方便了很多,而且还帮助避免了很多涉及到锁的常见编程错误,但有时也需要以更为灵活的方式使用锁。例如,某些遍历并发访问的数据结果的算法要求使用 "hand-over-hand" 或 "chain locking":获取节点 A 的锁,然后再获取节点 B 的锁,然后释放 A 并获取 C,然后释放 B 并获取 D,依此类推。Lock 接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,从而支持使用这种技术。

    随着灵活性的增加,也带来了更多的责任。不使用块结构锁就失去了使用 synchronized 方法和语句时会出现的锁自动释放功能。在大多数情况下,应该使用以下语句:

    Lock l = ...;
    l.lock();
    try {
        // access the resource protected by this lock
    } finally {
        l.unlock();
    }

    锁定和取消锁定出现在不同作用范围中时,必须谨慎地确保保持锁定时所执行的所有代码用 try-finally 或 try-catch 加以保护,以确保在必要时释放锁。

    Lock 提供了使用 synchronized 方法和语句所没有的其他功能,包括提供了一个非块结构的获取锁尝试 (tryLock())、一个获取可中断锁的尝试 (lockInterruptibly()) 和一个获取超时失效锁的尝试 (tryLock(long, TimeUnit))。

    tryLock()

    仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值 false。

    此方法的典型使用语句如下:

    Lock lock = ...;
    if (lock.tryLock()) {
        try {
            // manipulate protected state
        } finally {
            lock.unlock();
        }
    } else {
        // perform alternative actions
    }

    此用法可确保如果获取了锁,则会释放锁,如果未获取锁,则不会试图将其释放。

    tryLock(long, TimeUnit)

    如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。

    如果锁可用,则此方法将立即返回值 true。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下三种情况之一前,该线程将一直处于休眠状态:

    • 锁由当前线程获得;或者
    • 其他某个线程中断当前线程,并且支持对锁获取的中断;或者
    • 已超过指定的等待时间

    如果获得了锁,则返回值 true

    如果当前线程:

    • 在进入此方法时已经设置了该线程的中断状态;或者
    • 在获取锁时被中断,并且支持对锁获取的中断,

    则将抛出 InterruptedException,并会清除当前线程的已中断状态。

    如果超过了指定的等待时间,则将返回值 false。如果 time 小于等于 0,该方法将完全不等待。

    lockInterruptibly()

    如果当前线程未被中断,则获取锁。

    如果锁可用,则获取锁,并立即返回。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:

    • 锁由当前线程获得;或者
    • 其他某个线程中断当前线程,并且支持对锁获取的中断。

    如果当前线程:

    • 在进入此方法时已经设置了该线程的中断状态;或者
    • 在获取锁时被中断,并且支持对锁获取的中断,

    则将抛出 InterruptedException,并清除当前线程的已中断状态。

  • 相关阅读:
    417 Pacific Atlantic Water Flow 太平洋大西洋水流
    416 Partition Equal Subset Sum 分割相同子集和
    415 Add Strings 字符串相加
    414 Third Maximum Number 第三大的数
    413 Arithmetic Slices 等差数列划分
    412 Fizz Buzz
    410 Split Array Largest Sum 分割数组的最大值
    409 Longest Palindrome 最长回文串
    day22 collection 模块 (顺便对比queue也学习了一下队列)
    day21 计算器作业
  • 原文地址:https://www.cnblogs.com/huey/p/5993853.html
Copyright © 2011-2022 走看看