三.锁的相关概念介绍

在前面介绍了Lock的基本使用,这一节来介绍一下与锁相关的几个概念。

1.可重入锁

如果锁具备可重入性,则称作为可重入锁。像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。

看下面这段代码就明白了:

class MyClass {

public synchronized void method1() {

method2();

}

public synchronized void method2() {

}

}

上述代码中的两个方法method1和method2都用synchronized修饰了,假如某一时刻,线程A执行到了method1,此时线程A获取了这个对象的锁,而由于method2也是synchronized方法,假如synchronized不具备可重入性,此时线程A需要重新申请锁。但是这就会造成一个问题,因为线程A已经持有了该对象的锁,而又在申请获取该对象的锁,这样就会线程A一直等待永远不会获取到的锁。

而由于synchronized和Lock都具备可重入性,所以不会发生上述现象。

2.可中断锁

可中断锁:顾名思义,就是可以相应中断的锁。

在Java中,synchronized就不是可中断锁,而Lock是可中断锁。

如果某一线程A正在执行锁中的代码,另一线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想先处理其他事情,我们可以让它中断自己或者在别的线程中中断它,这种就是可中断锁。

在前面演示lockInterruptibly()的用法时已经体现了Lock的可中断性。

3.公平锁

公平锁即尽量以请求锁的顺序来获取锁。比如同是有多个线程在等待一个锁,当这个锁被释放时,等待时间最久的线程(最先请求的线程)会获得该所,这种就是公平锁。

非公平锁即无法保证锁的获取是按照请求锁的顺序进行的。这样就可能导致某个或者一些线程永远获取不到锁。

在Java中,synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。

而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。

看一下这2个类的源代码就清楚了:

在ReentrantLock中定义了2个静态内部类,一个是NotFairSync,一个是FairSync,分别用来实现非公平锁和公平锁。

我们可以在创建ReentrantLock对象时,通过以下方式来设置锁的公平性:

ReentrantLock lock = new ReentrantLock(true);

如果参数为true表示为公平锁,为fasle为非公平锁。默认情况下,如果使用无参构造器,则是非公平锁。

另外在ReentrantLock类中定义了很多方法,比如:

isFair()        //判断锁是否是公平锁

isLocked()    //判断锁是否被任何线程获取了

isHeldByCurrentThread()   //判断锁是否被当前线程获取了

hasQueuedThreads()   //判断是否有线程在等待该锁

在ReentrantReadWriteLock中也有类似的方法,同样也可以设置为公平锁和非公平锁。不过要记住,ReentrantReadWriteLock并未实现Lock接口,它实现的是ReadWriteLock接口。

4.读写锁

读写锁将对一个资源(比如文件)的访问分成了2个锁,一个读锁和一个写锁。

正因为有了读写锁,才使得多个线程之间的读操作不会发生冲突。

ReadWriteLock就是读写锁,它是一个接口,ReentrantReadWriteLock实现了这个接口。

可以通过readLock()获取读锁,通过writeLock()获取写锁。

上面已经演示过了读写锁的使用方法,在此不再赘述。

参考资料:

http://blog.csdn.net/ns_code/article/details/17487337

http://houlinyan.iteye.com/blog/1112535

http://ifeve.com/locks/

http://ifeve.com/read-write-locks/

http://blog.csdn.net/fancyerii/article/details/6783224

http://blog.csdn.net/ghsau/article/details/7461369/

http://blog.csdn.net/zhaozhenzuo/article/details/37109015

Java并发编程:Lock(下)相关推荐

  1. java并发编程:lock_编程的第五个十年:J代表Java

    java并发编程:lock 一段非常个人的编程历史中的第五章第一部分 在自己的一类 尽管Microsoft并不认同Oracle对Java的所有雄心壮志,但我们同意它对于软件开发人员来说是非常有价值的工 ...

  2. Java并发编程(06):Lock机制下API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Lock体系结构 1.基础接口简介 Lock加锁相关结构中涉及两个使用广泛的基础API:ReentrantLock类和Condition接 ...

  3. java 多线程缓存_[Java教程]【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列...

    [Java教程][JAVA并发编程实战]12.使用condition实现多线程下的有界缓存先进先出队列 0 2016-11-29 17:00:10 package cn.study.concurren ...

  4. JUC里面的相关分类|| java并发编程中,关于锁的实现方式有两种synchronized ,Lock || Lock——ReentrantLock||AQS(抽象队列同步器)

    JUC分类 java并发编程中,关于锁的实现方式有两种synchronized ,Lock AQS--AbstractQueuedSynchronizer

  5. 6. Java并发编程-并发包-Lock和Condition

    前文介绍了java语言本身通过synchronized, wait, notify实现了管程,解决了并发编程两大难题:互斥和同步. 这两大问题并发包中也得到了相应的实现,分别时Lock和Conditi ...

  6. Java并发编程71道面试题及答案

    Java并发编程71道面试题及答案 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方 ...

  7. 基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程

    许多以Java多线程开发为主题的技术书籍,都会把对Java虚拟机和Java内存模型的讲解,作为讲授Java并发编程开发的主要内容,有的还深入到计算机系统的内存.CPU.缓存等予以说明.实际上,在实际的 ...

  8. Java并发编程,无锁CAS与Unsafe类及其并发包Atomic

    为什么80%的码农都做不了架构师?>>>    我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...

  9. Java并发编程之介绍

    并发编程简介 将串行执行部分编程并发执行,但要考虑上下文切换和资源调度的时间 并发编程的意义及影响多线程的因素 并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最 大限度地并 ...

  10. Java并发编程:CopyOnWrite容器的实现

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

最新文章

  1. 有人把机器学习的数学基础整理成了专辑(附下载 )
  2. Python高级网络编程系列之第二篇
  3. matlab怎么调用DeepLearn,使用DeepLearnToolbox-master中DBN工具箱做数据分类出现问题,求......
  4. 在SQL Server中分页结果的最佳方法是什么
  5. 风变编程的python课程怎么样-高效学风变编程Python,解锁不一样的职场进阶之路...
  6. hadoop中如何动态更新集群队列和容量
  7. leetcode 119. 杨辉三角 II
  8. macbook不能进系统 备份数据_不基于备份和表,生产系统数据误删就能完全恢复?!...
  9. Mybatis SQL片段
  10. 谷歌地球最新host_听说《流浪地球》被豆瓣鄙视了,我们用数据看一把真相(上)...
  11. vs2012 使用mysql_vs2012连接mysql
  12. 首席架构师眼中的架构应该是怎样的?
  13. gcc 如何编译cpp文件啊
  14. 史丰收速算-第五届蓝桥杯省赛
  15. div内li标签间距_css怎样让li间距增大?
  16. (python)爬虫----八个项目带你进入爬虫的世界
  17. html5 竖线的实现,border 实现竖线
  18. 【mysql】mysql 中 text,longtext,mediumtext 字段类型的意思, 以及区别
  19. Oracle索引的理解
  20. 3.Python3标准库--数据结构

热门文章

  1. 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第4节 maven生命周期和概念模型图_09maven概念模型图...
  2. 百度地图电子围栏功能的实现
  3. PL/SQL developer连接远程ORACLE
  4. oracle的loop等循环语句的几个用法小例子[转]
  5. Flask 蓝图(Blueprint)
  6. 九度OJ 1340:小A的计算器 (进制转换)
  7. memcached SASL验证状态安全绕过漏洞
  8. 用户体验报告(Echo)
  9. markdown 常用语法格式
  10. 表达式求值(栈方法/C++语言描述)(一)