线程知识学习五——并发
来源:互联网 发布:查看软件的注册表 编辑:程序博客网 时间:2024/04/29 15:15
继上篇博客多线程的并发,我们提到了一种同步互斥的解决方案——synchronized,这篇博客,我们来说说其他解决方案。
lock
还是老规矩,在开始文字描述前,我们先来看看我们的学习思路:
我们介绍图中的前两个:
1、我们是如何使用lock的?
2、lock和synchronized的对比,为什么有了synchronized又有了lock呢?
先看第一个:我们是如何使用lock的。lock是在Java5以后专门提供了锁对象,利用锁可以方便的实现资源的封锁,用来控制对竞争资源并发访问的控制,主要集中在java.util.concurrent.locks 包下面。
ReenTrantLock
ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。
以下是一个简单的Reentrantlock实现的Demo。
import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class Printer { private Lock lock = new ReentrantLock();// 锁对象 public void printLetters(char c) { lock.lock();// 得到锁 try { for(int i = 0; i<5; i++) { System.out.print(c); } System.out.println(); }finally { lock.unlock();// 释放锁 } }}
值得注意的是:
ReentrantLock需要我们手动去关闭,我们一般是在结合try……catch语句块来使用,在finally中,手动释放锁。
ReentrantLock获取锁定的方式
1. lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁;
2. tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
3. tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
4. lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断。
实现lock接口的类还哟:ReentrantReadWriteLock,其内部类包含ReadLock与WriteLock;其功能更强大。
Lock与Synchronized区别
1、ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候
线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,
如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断
如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情
2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中。
总结
synchronized:在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的。原因在于,编译程序通常会尽可能的进行优化synchronize,另外可读性非常好,不管用没用过5.0多线程包的程序员都能理解。
ReentrantLock: 提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。
- 线程知识学习五——并发
- 线程知识学习 四 ——并发
- 线程知识学习六——并发(辅助类)
- 线程知识学习七——并发(辅助类)
- 线程并发学习—-ConcurrentHashMap
- Java并发学习之五——线程的睡眠和恢复
- kinect学习笔记五(线程并发)
- Java并发编程(五)——线程间通信
- Java并发——线程中断学习
- 锁对象——线程学习五
- 线程知识的学习 二——线程基础
- java线程学习(九)—并发编程实践学习
- Java 并发编程深入学习(五)——死锁
- 关于Java多线程和并发运行的学习(五)——并发 Collection
- java学习——java高级特性,线程,并发 笔记
- Java并发学习之一——线程的创建
- Java并发学习之三——线程的中断
- Java并发学习之七——守护线程
- 模仿自定义View的一个小例子
- 黑马程序员-------面向对象(下)
- IE6 IE7 IE8 IE9 IE10 Css hack及IE条件注释法
- Android中补间动画的实现之二
- 非谓语动词---不定式作名词
- 线程知识学习五——并发
- [转] iOS --- 应用架构谈之二: View层的组织和调用方案
- alpha测试和beta测试
- Activity的生命周期的运行情况
- 九度1106
- 1040: [ZJOI2008]骑士
- zigbee协议栈学习(四)
- 沉痛记下这次与 mysql 的交锋,以全面溃败结束
- hive select查询语句