java.util.concurrent.locks.Lock文档说明

【1】Lock接口文档描述

1.相比于使用synchronized方法和代码块,锁的出现提供了更广泛的锁操作。

锁允许更灵活的代码结构,具有许多不同的属性,还支持多个关联的Condition条件对象

2.锁是用于控制多个线程访问共享资源的工具。通常,锁提供了对共享资源的独占(排他)访问,即某一时刻,只能有1个线程可以获得锁,所有对共享资源的访问都必须事先获得锁。

然而,一些锁允许对共享资源的并发访问,读写锁 ReadWriteLock的读锁

3.使用synchronized方法或代码块进行并发控制,实际是对每个对象的隐式监视器锁(monitorenter+monitorexit)的访问,且强制让锁的获取与释放发生在块结构中。当获取了多个锁,这些锁需要相反的顺序释放。而且所有锁必须在它们被获取时的作用域里释放;

4.虽然 synchronized方法与代码块的作用域机制使得使用监视器锁编码更加容易,也有助于避免许多常见的涉及锁的变成错误,但某些情况下,你需要以更加灵活的方式使用锁

如一些并发遍历数据结构的算法需要使用 交叉(hand-over-hand)或链锁(chain lock):你先获取节点A的锁,接着B,然后释放A,获取C,然后释放B....等等。

还比如,使用可中断方式,或非阻塞方式获取锁,或超时方式获取锁(超时前阻塞,超时后立即返回,无论获取锁与否),而不是像 synchronized那样一直阻塞,不可中断,没有超时机制(非常死板)(干货——为什么需要使用Lock而不是synchronized实现锁)

Lock接口的实现允许在不同的作用域获取和释放锁,并允许以任意顺序获取和释放锁。

Lock接口 与 synchronized 进行并发控制的最大区别小结:

  1. synchronized:获取锁与释放锁在同一个作用域内(代码块内);且锁的释放顺序必须与获取顺序相反(字节码指令 monitorenter加锁,monitorexit解锁);
  2. Lock接口: 获取锁与释放锁可以在不同的作用域内; 锁的释放顺序与获取顺序任意(Lock接口方法lock()加锁,unlock()解锁);

5.这种增加的灵活性带来了额外的责任。Lock接口没有使用代码块结构,这样消除了synchronized中的锁自动释放功能。

6.在大多数情况下,应该使用以下语句进行 Lock对象的锁获取与释放

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

7.当锁的获取与释放发生在不同作用域时,需要特别注意,让持有锁时执行的所有代码都在 try-finally 或 try-catch 块中受到保护,以确保必要时释放锁

8.Lock的实现比synchronized多提供了其他方法(更加灵活,或者两者的不同点,如

tryLock()方法-通过非阻塞方式尝试获取锁;
lockInterruptibly() 方法-尝试获取的锁,获取过程可被中断;
tryLock(long time, TimeUnit unit) -有超时限制的尝试获取锁(超时后,立即返回,不会一直阻塞);

9.Lock还提供了与隐式监视器锁不同的行为和语义,如保证有序,非重入使用,死锁检测。如果锁的实现提供了这样专门的语义,则该实现必须记录这些语义。

10.注意: Lock实例仅仅是普通对象,Lock对象本身可以作为synchronized语句的目标对象,如

synchronized(LockIntance){...}

获取Lock实例的监视器锁与 调用Lock实例的lock方法没有关系。墙裂建议不要在 synchronized语句块中获取Lock实例的监视器锁,以避免混淆

11.内存同步

所有Lock的实现都必须强制相同的内存同步语义(内存可见性),就像内建的监视器锁一样,据java语言规范所描述的那样:成功的锁定操作与成功的Lock动作有相同的内存同步效果,不成功的锁定操作与不成功的UnLock动作有相同的内存同步效果。不成功的加锁和解锁操作,可重入加锁和解锁操作,不要求任何的内存同步效果;

12. Lock实现类注意事项

获取Lock锁的3种方式,包括可中断,不可中断,超时,在性能特征,顺序保证,和其他方面都不相同。此外,在给定Lock类中,可能无法中断获取锁的过程。因此,不需要为3种方式定义相同的保证与语义,也不需要支持对锁获取的中断。锁的实现需要清楚记录每个锁方法的语义和保证。Lock实现类也必须遵守如接口中定义的中断语义,当需要支持锁获取的中断的时候,完全或仅有一个方法入口。

13.中断意味着取消,但中断检测不常发生,因此锁的实现(Lock接口实现类)倾向于响应中断而不是从方法返回

即使证明了另一个动作之后发生的中断会解除线程阻塞,也是如此。锁的实现应该记录这些行为。


【2】Lock方法描述

【2.1】void lock()

获取锁;如果锁不可用(获取锁失败),则当前线程将被线程调度器禁用,并休眠直到可以获得锁(当前线程阻塞)

Lock接口实现类注意事项:

Lock接口的实现类可能探测到锁的错误使用,如死锁,并在这种情况下抛出异常(未检测异常)。Lock的实现必须记录这种情况和异常类型。


【2.2】void lockInterruptibly() throws InterruptedException;

1.获取锁,除非当前线程中断;

2.如果锁可用,则获取锁并立即返回。

3.如果锁不可用(获取锁失败),则当前线程将被线程调度器禁用,并休眠直到出现以下两种情况之一(当前线程阻塞)

  • 情况1,当前线程获取锁;
  • 情况2,某个其他线程中断了当前线程(当Lock实现类支持获取锁时的中断);

4.如果当前线程:

在方法入口设置了中断状态,或者在获取锁时被中断了,则会该线程抛出 中断异常InterruptedException,且其中断状态被清除。

5.Lock实现类注意事项

在某些Lock接口的实现类中,中断一个获取锁的线程是不可能的,如果可能,那也是非常昂贵的操作。程序员应该注意这种情况。Lock的实现也应该记录这种情况。

6.与正常方法返回相比,Lock实现类更倾向于响应中断

7.Lock实现类可能探测到锁的错误使用,如死锁,并在这种情况下抛出异常(未检测异常)。Lock的实现类必须记录这种情况和异常类型。

8.抛出异常:

InterruptedException-可中断异常,若当前线程在获取锁时被中断了


【2.3】boolean tryLock()

1.只要当前线程调用该方法时锁是空闲的,则获取锁;

2.如果锁可用,则获取锁并立即返回true;如果锁不可用,则立即返回flase(当前线程不会阻塞)

3.典型用法如下:

Lock lock = ...;if (lock.tryLock()) {try {// 操作保护的状态} finally {lock.unlock();}} else {// 执行替代操作 }

这种用法确保了在获取锁时可以解锁,在没有获取锁时不会尝试解锁。

返回:若获取锁返回true,否则返回false;


【2.4】boolean tryLock(long time, TimeUnit unit) throws InterruptedException

1.如果锁在给定等待时间内是空闲的且当前线程没有被中断,则当前线程获取锁

2.若锁可用,该方法立即返回true。若锁不可用,则当前线程无法被调度器调度,且会阻塞直到发生以下3种情况之一(当前线程阻塞)

  • 情况1, 当前线程获取锁;
  • 情况2, 其他线程中断当前线程(当Lock实现类支持锁获取时的中断);
  • 情况3,经过了给定等待时间,成功获取了锁则立即返回true;

3.如果当前线程:

在方法入口设置了中断状态,或者当前线程在获取锁时被中断了(当Lock实现类支持获取锁时的中断),则该线程抛出 中断异常InterruptedException,且中断状态被清除。

4.与正常方法返回或报告超时相比,Lock实现类更倾向于响应中断

5.Lock接口的实现类可能探测到锁的错误使用,如死锁,并在这种情况下可能抛出异常(未检测异常)。Lock的实现类必须记录这种情况和异常类型。

6.参数列表:

  • time, 等待锁可用的最大时间;
  • unit, time的时间单位,如时、分、秒

7.返回:

若获取到锁,返回true;若经过等待时间没有获取到锁,返回false;

8.抛出异常:

InterruptedException-可中断异常,若当前线程在获取锁时被中断了(当Lock实现类可以支持获取锁时的中断);


【2.5】void unlock() -释放锁。

1.Lock实现类的注意事项:

Lock实现类通常会对释放锁的线程施加限制(典型情况是只有锁的持有者可以释放锁),且若违反限制,则可能抛出异常(unchecked)。

Lock实现类必须记录任何限制和异常。


【2.6】Condition newCondition()

1.返回绑定到此Lock实例的新的Condition实例

2.在等待condition之前,当前线程必须持有锁。

3.调用Condition.await() 方法会在等待之前自动释放锁,并在等待返回之前重新获取锁;

4.Lock实现类注意事项

Condition实例的正确操作依赖于Lock的实现类。Lock实现类必须记录这些操作。

5.返回:

该Lock实例的新的Condition实例;

6.抛出异常:

UnsupportedOperationException-不支持的操作异常-若锁实现类不支持 condition;


【3】Lock方法总结

【3.1】Lock获取锁方法

方法描述

当前线程

是否阻塞

void lock()获取锁;如果锁不可用(获取锁失败),则当前线程将被线程调度器禁用,并休眠直到可以获得锁(当前线程阻塞);阻塞(不可中断)
void lockInterruptibly() throws InterruptedException

1.获取锁,除非当前线程中断;
2.如果锁可用,则获取锁并立即返回。
3.如果锁不可用(获取锁失败),则当前线程将被线程调度器禁用,并休眠直到出现以下两种情况之一(当前线程阻塞)。
    情况1,当前线程获取锁;
    情况2,某个其他线程中断了当前线程(当Lock实现类支持获取锁时的中断);

阻塞

(但可中断)

boolean tryLock()1.只要当前线程调用该方法时锁是空闲的,则当前线程获得锁;
2.如果锁可用,则获取锁并立即返回true;如果锁不可用,则立即返回flase(当前线程不会阻塞)
不阻塞
boolean tryLock(long time, TimeUnit unit) throws InterruptedException

1.如果锁在给定等待时间内是空闲的且当前线程没有被中断,则当前线程获取锁;
2.若锁可用,该方法立即返回true。若锁不可用,则当前线程无法被调度器调度,且会阻塞直到发生以下3种情况之一(当前线程阻塞):
    情况1, 当前线程获取锁;
    情况2, 其他线程中断当前线程(当Lock的实现类支持锁获取时的中断);
    情况3,经过了给定等待时间,成功获取了锁则立即返回true,若没有获取到锁则返回false;

阻塞

(可中断,且超时后立即返回,无论获取锁与否)


【3.2】Lock其他方法

void unlock,释放锁;

Condition newCondition(), 获取新的Condition实例;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20 个使用 Java CompletableFuture的例子

转载自 20 个使用 Java CompletableFuture的例子这篇文章介绍 Java 8 的 CompletionStage API和它的标准库的实现 CompletableFuture。API通过例子的方式演示了它的行为,每个例子演示一到两个行为。既然CompletableFuture类实现了CompletionStage接口,首…

fastreport 打印两个list_Smaller And Smarter Python数据结构:合并两个有序链表

原创: 老表 简说Python 今日问题 :翻转链表k个相邻结点"""目标:写一段程序,合并两个有序链表例如:输入-> 1->2->3输入-> 2->5->6->8输出-> 1->2->2->3->5->6-&…

java.util.concurrent.locks.Condition文档说明

【1】Condition接口文档描述 1.Condition类把Object监视器方法(wait,nofify, notifyAll)分解为不同对象,通过与Lock实现类的合并使用,Condition可以产生每个object都有多个等待集的效果。在Lock实现类替代synchronized方法或语句…

谈谈HashMap线程不安全的体现

转载自 谈谈HashMap线程不安全的体现HashMap的原理以及如何实现,之前在JDK7与JDK8中HashMap的实现中已经说明了。那么,为什么说HashMap是线程不安全的呢?它在多线程环境下,会发生什么情况呢?1. resize死循环我们都知道…

手机打开python文件_使用python在计算机和手机之间通过wifi进行简单的文件传输...

我会使用 paramiko.它安全快速而且非常简单.怎么回事? 所以我们首先导入模块,然后指定日志文件: import paramiko paramiko.util.log_to_file(/tmp/paramiko.log) 我们打开一个SSH传输: host "example.com" port 22 transport p…

10人以下小团队管理手册-学习笔记

【README】 本文总结于《10人以下小团队管理手册》,很nice的一本书,有兴趣的同学可以翻下; 【0】序章 作者作为咨询师发现, 1.下属对主管有不满,主管对下属有怨言; 2.10人以下小团队主管经常会为 如何用…

JavaWeb项目:简易小米商城系统

Web项目:MyShop简易小米商城系统一.系统概述二.系统开发环境三.涉及技术四.系统功能及使用说明五.作者杂谈六.尾声七.gitee地址:(源码见文末) 一.系统概述 本系统是一个电商系统,可供用户注册,登录&#…

HashMap的实现与优化

转载自 HashMap的实现与优化HashMap的优化与实践 本文是基于作者在github上的Android 问题交流讨论坛提问而产生的一篇文章,也是自己早打算开坑的一篇文章。文章首先介绍了hashMap的一些基本知识,然后介绍了它在JDK8下的实现原理,最后着重介绍…

如何确定python开发环境已经配置好_搭建 python 开发环境 前面安装选位置我直接回车了现在我想测试查看目录该怎么办...

展开全部 1 ubuntu中一般安装e5a48de588b662616964757a686964616f31333431343036后的默认路径如下#!/usr/bin/env python #!/usr/locat/bin/python 如果没有找到,可以通过命令查询python路径whereis python which python 2 Windows一般可以进入python>>> i…

转- java单例模式几种实现方式

转自: https://www.cnblogs.com/ngy0217/p/9006716.html ; 单例模式的五种实现方式 1、饿汉式(线程安全,调用效率高,但是不能延时加载): 1 2 3 4 5 6 7 public class ImageLoader{ private static ImageLoade…

IDEA集成maven流程图详细介绍

前言 最近利用两天时间学习了MyBatis以及maven,避免经典的学过就忘记,我打算做出点总结以便日后复习,当然如果能帮到需要的人也是极好的。 一. 初识maven 1.maven是什么 maven是用来帮助我们快速搭建项目结构与开发环境的好工具。回想一下每次新建项…

pythonnumpy教程_Python教程:numpy的基本介绍

标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。对于数值运算来说这种结构显…

Java8系列之重新认识HashMap

转载自 Java8系列之重新认识HashMap简介 Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap、Hashtable、LinkedHashMap和TreeMap,类继承关系如下图所示:下面针对各个实现类的特点做…

mysql-on duplicate key update实现insertOrUpdate官方文档

【README】 mysql 基于 on duplicate key update filedvalue ; 实现有则更新,没有则插入; 以下内容总结于 https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html 【1】api 描述 如果指定 ON DUPLICATE KEY UPDATE 子句并且要插入的行…

python统计段落单词词频_使用Python统计文件中词频,并且生成词云

wordcloud Table of Contents 1 怎样使用Python产生词云 from wordcloud import WordCloud import matplotlib.pyplot as plt import jieba # Now, There is no word.txt under this path path_txt "/home/alan/Desktop/word.txt" f open(path_txt, r, encoding U…

IDEA中maven配置MyBatis简单流程

前言 刚学完javaweb,对自己的Dao层代码很不满意的话,可得来学学MyBatis。学习MyBatis既可以改进JDBC的使用,实现Dao层也会变得很简便,下面我将介绍IDEA中maven配置MyBatis简单流程。 如果想了解maven请转到我的上一篇文章中&…

(转)构建微服务:Spring boot 入门篇

转自: Spring Boot(一):入门篇 - 纯洁的微笑 - 博客园 ; 什么是Spring Boot Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#…

python参数_python参数的介绍

一、函数 1.为什么要使用函数? 减少代码的冗余 2.函数先定义后使用(相当于变量一样先定义后使用) 3.函数的分类: 内置函数:python解释器自带的,直接拿来用就行了 自定义函数:根据自己的需求自己…

一篇文章指明做JavaWeb项目需要的前置知识+完整项目初解读(萌新必看,十分友好)

前言 过了web这个阶段了,项目也完成了的我想给各位后来者总结一下我整个项目从开始到结束的经验,当然,也不是一帆风顺,报错有时候折磨的要死,废话不多说,现在就开始吧。 本文一共分为两个部分:…

HashMap 实现原理

转载自 HashMap 实现原理HashMap是常考点,而一般不问List的几个实现类(偏简单)。以下基于JDK1.8.0_102分析。 内部存储 HashMap的内部存储是一个数组(bucket),数组的元素Node实现了是Map.Entry接口(hash, key, value, next)&#…