`
Tonyguxu
  • 浏览: 271676 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Java并发】锁

 
阅读更多

简介

 

 

        锁是控制多个线程对共享资源访问(读/写,读:读内容;写:修改内容+删除文件)的工具。通常,锁提供了对共享资源的独占访问:对共享资源的任何访问都需要首先获取锁,一次只能有一个线程获取锁。

 

       锁不仅是关于同步和互斥 的,也是关于内存可见 的。为了保证所有线程都能够看到共享的/可变变量的最新值,读取和写入线程必须使用公共的锁进行同步。

 

     针对有读/写两种不同访问方式,能不能做的更智能一些,有没有锁机制能允许对共享资源并发“读”访问,利用 ReadWriteLock 的读锁可以!!。

 

JDK 1.5 之前,协调共享对象 的访问(coordinate access to shared data )能采取的机制是synchronized volatile 。在1.5 后,通过显式定义同步锁对象(Lock对象)来实现同步,增加了ReentrantLock 。这样,大致可将锁分为implicit lock(内部锁)explicit lock(显示锁)。

 

 

一些概念

同步和互斥

当多个线程对共享资源访问的时候,很有可能会带来线程安全问题,可以通过同步监视器(synchronized同步块or同步方法)。

 

独占锁,互斥锁

 

死锁

两个线程互相等待对方释放同步监视器时就会发生死锁。一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,所有线程处于阻塞状态。

 

用锁来保护状态

一个错误观念:只有在写入共享变量时才需要同步。



构造线程安全类一种常见的锁规则:

在对象内部封装可变状态,通过对象的内部锁 来同步任何对这些可变状态访问的代码路径,从而保证在并发访问中的安全。


Synchronized


同步方法和同步代码块的粒度:

同步方法可能会带来活跃度与性能的问题,通过缩小synchronized块的范围我们既可以维护线程安全性,还能比较容易地提升并发性。但也不能让synchronized太小:不可以将一个原子操作分解到多个synchronized块中。不过应该尽量从synchronized块中分离耗时的且不影响共享状态的操作(参考并发编程实践p30) 。对于独享地操作本地(基于栈)变量,这些变量不被多线程共享,可以不放在同步块当中。

重进入(Reentrancy)

内部锁是可以重进入的,即线程在试图获取它自己占有的锁时,请求会成功。重进入的实现是通过为每个锁关联一个请求计数和一个占有它的线程。

 

 

何时释放同步监视器的锁定?

 

 

Lock接口

 

 

Lock lock = new ..;
...
lock.lock();
try{
//需要锁保护的更新对象的状态
}finally{
lock.unlock();
}

 finally千万不能丢!!

 

Lock接口实现类有:    ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock。

其中ReentrantLock实现了标准的互斥锁。

 

ReentrantLock

 

可重入

线程可以对它已经加锁的ReentrantLock锁再次加锁。所以一段被锁保护的代码可以调用另一个被相同锁保护的代码。

 

synchronized ReentrantLock 间选择

使用 ReentrantLock 时有些要额外注意的地方,比如在 finally 里调用 unlock()

ReentrantLock 可伸缩性( scalability )更好。--如何理解??

对于如何选择可以遵循这样的原则:在内部锁不能满足需求时,再考虑使用 ReentrantLock (内部锁能处理哪些问题??)当需要一些高级特性 时, ReentrantLock 才应该被使用:可定时的( timed )、可轮询的( polled )、可中断的( interruptible )锁获取操作,公平队列,非块结构锁( none-block-structured )。

 

Volatile

读一个 volatile 变量时,总能返回由某一线程写的最新值。 Volatile 的一个典型应用是:检查状态标记(完成、中断、其他状态)

访问volatile变量的操作不会加锁,也就不会引起执行线程的阻塞,volatile相对synchronized而言可以说是轻量级的同步机制。

Volatile 只能保证变量的“可见性 ”,却不能保证“原子性”。(相比较:加锁既能保证可见性也能保证原子性)。

示例

// 判断是否睡觉,没有的话继续数数,如果已睡,则停止数数。

volatile boolean asleep;

while(!asleep){

   countNum();

}

在考虑使用 volatile 时,思考下面问题

1. 写入变量时是否依赖变量的当前值?或者是否只有一个线程执行写操作?

如果不依赖或者能确定只有一个线程写则可以考虑

2. 变量是否要与其他变量一起参与不变约束?

如果没有则可以考虑。

3. 访问变量时,是否有其他原因需要加锁?

如果没有则可以考虑。


关于CAS和原子变量的信息可参见http://kenwublog.com/the-theory-of-volatile


 

 

 

 

读-写锁

读写锁能够保证一个资源能同时被多个读者访问,或者只被一个写者访问。当对容器“读”操作较多,而很少写的时候,使用ReadWriteLock比使用ReentrantLock能获得更高的吞吐量。如为LinkedHashMap提供更高的并发访问。

ReadWriteLock lock = new ReentrantReadWriteLock();
Lock w = lock.writeLock();//获得"写锁"实例
Lock r = lock.readLock()//获得“读锁”实例

//对写操作加锁
w.lock();
try{
   //write operation
}finally{
   w.unlock();
}
//对读操作加锁
r.lock();
try{
   //read operation
}finally{
   r.unlock();
}
 

 

能够用同一个读写锁保护不同的资源么?

 

阅读材料

http://wenku.baidu.com/view/a0104d39580216fc700afd90.html

http://www.jdon.com/concurrency.html

【公司源码查看】: UserAccountLockService

分享到:
评论

相关推荐

    java并发锁面试知识

    java中的乐观锁与悲观锁,synchronized与ReentrantLock重入锁的说明与比较

    Java并发锁简介-动力节点共9页.pdf.zip

    Java并发锁简介__动力节点共9页.pdf.zip

    JAVA并发编程艺术 高清pdf

    JAVA并发编程艺术 高清pdf : 1.并发变成的挑战 2. java并发机制的底层实现原理 3. java 内存模型 4. java并发编程基础 5.java中的锁。。。。。。。

    Java 并发核心编程

    自从java创建以来就已经支持并发的理念,如线程和锁。这篇指南主要是为帮助java多线程开发人员理解并发的核心概念以及如何应用这些理念。本文的主题是关于具有java语言风格的Thread、synchronized、volatile,以及...

    《java 并发编程实战高清PDF版》

    深入讲解java并发编程技术,多线程、锁以及java内存模型等

    Java 并发编程实战.pdf

    《java并发编程实战》是java并发的圣经。亲自整理目录结构,层级分明(福昕阅读器整理)。高清。

    Java并发编程实战

    1.1 并发简史 1.2 线程的优势 1.2.1 发挥多处理器的强大能力 1.2.2 建模的简单性 1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 ...

    《Java并发编程的艺术》

    《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时...

    JAVA并发编程实践 .pdf

    《Java并发编程实战》深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证...

    java并发编程与高并发处理.xmind

    java并发编程总结,为xmind格式,总结的很详细,包含常见的并发容器,锁等知识

    Java并发编程Xmind思维导图

    Java并发编程Xmind思维导图,思路更清晰。内容来自《Java并发编程的艺术》,包括并发机制底层原理、Java内存模型、Java并发编程基础、锁机制、线程池、并发工具类、原子操作类、并发容器和框架。纯手打,非诚勿扰。

    《Java并发编程的艺术》源代码

    Java并发编程的艺术 作者:方腾飞 魏鹏 程晓明 著 丛书名:Java核心技术系列 出版日期 :2015-07-25 ISBN:978-7-111-50824-3 第1章介绍Java并发编程的挑战,向读者说明进入并发编程的世界可能会遇到哪些问题,以及如何...

    Java并发编程技术总结

    Java并发编程技术总结,所含内容有并发特性、并发锁、线程池、并发场景解决方案等,对于性能思考和内容参考资料有一定说明

    java并发规范(线程及锁).docx

    java并发规范,根据阿里整合

    Java并发编程实战.rar

    《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...

    java并发工具包 java.util.concurrent中文版用户指南pdf

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    Java并发编程的艺术

    , 《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,...

    JAVA并发编程实践 带书签

    本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...

Global site tag (gtag.js) - Google Analytics