Java并发编程与技术内幕:聊聊锁的技术内幕(上)
来源:互联网 发布:linux解压tar命令 编辑:程序博客网 时间:2024/06/05 06:18
转自http://blog.csdn.NET/evankaka
一、基础知识
在Java并发编程里头,锁是一个非常重要的概念。就如同现实生活一样,如果房子上了锁。别人就进不去。Java里头如果一段代码取得了一个锁,其它地方再想去这个锁(或者再执行这个相同的代码)就都得等待锁释放。锁其实分成非常多。比如有互斥锁、读写锁、乐观锁、悲观锁、自旋锁、公平锁、非公平锁等。包括信号量其实都可以认为是一个锁。
1、什么时需要锁呢?
其实非常多的场景,如共享实例变量、共享连接资源时以及包括并发包中BlockingQueue、ConcurrentHashMap等并发集合中都大量使用了锁。基体上使用同步的地方都可以改成锁来用,但是使用锁的地方不一定能改成同步来用。
2、 锁和同步的对比
1)同步synchronized算是一个关键词,是来来修饰方法的,但是锁lock是一个实例变量,通过调用lock()方法来取得锁
2)、只能同步方法,而不能同步变量和类,锁也是一样
3)、同步无法保证线程取得方法执行的先后顺序。锁可以设置公平锁来确保。
4)、不必同步类中所有的方法,类可以同时拥有同步和非同步方法。
5)、如果线程拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁的限制。锁也是一样。
6)、线程睡眠时,它所持的任何锁都不会释放。
7)、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。
8)、同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。
9)、在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。例如:
最后,还需要说的一点是。如果使用锁,那么一定的注意编写代码,但不很容易出现死锁!避免方法后文后讲。
3、简单实例
在看锁的源码时,首先来看个锁的实例,从而对锁有一个简单的理解。由线程A输出1、2、3.接着线程B输出4、5、6.最后线程A再输出7、8、9
输出结果:
这个题目用同步的方法也做其实也可以。但是用锁可能更好一点。在上面笔者使用了锁和条件从而完成 了要求。
二、说说源码
最基础的我们先来看看lock方法
1、接下来看看它最常见的实现类,ReentrantLock可重入锁。
2、构造函数
其里的公平锁的意思是哪个线程先来等待,谁就先获得这个锁。而非公平锁则是看操作系统的调度,有不确定性。一般设置成非公平锁的性能会好很多。3、然后看看lock方法还有这个
发现都 是调用 sync这个变量的方法,它其实是一个ReentrantLock的内部类。真实起作用的其实是它,所以直接看它源码:
首先是非公平锁:
它使用到的方法如下:最终取得锁的方法其实在java Unsafe类的compareAndSwap方法。compareAndSwap是个原子方法,原理是cas.就是说如果他是xx,那么就改为xxx. 这个是高效,而且是原子的,不用加锁. 也不用但是其他值改了而产生误操作,应为会先判断当前值,符合期望才去改变.4、tryLock()方法
上面是lock方法是的调用,如果是tryLock呢?
再看sync的方法其中getState()方法是在AbstractQueuedSynchronizer类的就方法,取得就是下面这个变量
在互斥锁中它表示着线程是否已经获取了锁,0未获取,1已经获取了,大于1表示重入数。同时AQS提供了getState()、setState()、compareAndSetState()方法来获取和修改该值:
5、tryLock(long timeout, TimeUnit unit)方法
带有超时时间等待获取锁的方法。真正调用 的其实是Sync父类AbstractQueuedSynchronizer的方法
这里调用 了两个方法tryAcquire和doAcquireNanos,其实tryAcquire调用的方法就是Lock()调用的方法这样就不再说明。下面直接来看doAcquireNanos方法,它才是一直在等待循环获取锁的方法。
锁的介绍就到这里了,下文再来接着讲~
- Java并发编程与技术内幕:聊聊锁的技术内幕(上)
- Java并发编程与技术内幕:聊聊锁的技术内幕(上)
- Java并发编程与技术内幕:聊聊锁的技术内幕(上)
- Java并发编程与技术内幕:聊聊锁的技术内幕(中)
- Java并发编程与技术内幕:聊聊锁的技术内幕(中)
- Java并发编程与技术内幕:聊聊锁的技术内幕(中)
- Java并发编程与技术内幕
- Java并发编程与技术内幕:线程池深入理解
- Java并发编程与技术内幕:Callable、Future、FutureTask、CompletionService
- Java并发编程与技术内幕:ThreadGroup线程组应用
- Java并发编程与技术内幕:ThreadFactory、ThreadLocal
- Java并发编程与技术内幕:ThreadFactory、ThreadLocal
- Java并发编程与技术内幕:ConcurrentHashMap源码解析
- Java并发编程与技术内幕:CopyOnWriteArrayList、CopyOnWriteArraySet源码解析
- Java并发编程与技术内幕:线程池深入理解
- Java并发编程与技术内幕:Callable、Future、FutureTask、CompletionService
- Java并发编程与技术内幕:线程池深入理解
- Java并发编程与技术内幕:消费者-生产者模式研究
- 粒子群算法(1)----粒子群算法简介
- HttpURLConnection post set params 设置请求参数的三种方法
- Qt实现基本QMainWindow主窗口程序
- Eclipse 自动生成注释信息
- HDU2042_不容易系列之二
- Java并发编程与技术内幕:聊聊锁的技术内幕(上)
- angularJs入门之购物车实现
- 选择排序
- 如何设计Lighthoused定位接收电路
- unity 学习笔记(改变物体旋转中心)
- python中的类方法与静态方法的区别
- js的查找
- 在Ubuntu环境中搭建OpenCV2411,并解决libgtk库更新问题
- 赛码网—在线编程(三)翻转数组