网站首页 > 文章精选 正文
在多线程开发中,锁是线程控制重要途径。
Java为此也提供了2中锁机制,synchronized和Lock(ReentrantLock)
原理
synchronized每一个对象都可以作为锁,这是synchronized
- . 普通同步方法,锁是当前实例对象
- . 静态同步方法,锁是当前类的class对象
- . 同步方法块,锁是括号里的对象
利用javap工具 (javap是java编译之后的class文件的分解器)查看生成的class文件信息来分析synchronized的实现。
package com.breeze.java
public class SynchronizedTester{
public synchronized void m1(){
};
public void m2(){
synchronized(this){
}
}
}
javap -help
javap -c -p SynchronizedTester.class
从图片中可以看出,同步代码块是使用的monitorenter 和monitorexit指令来实现的,同步方法(在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。
区别
两种锁的机制区别:
synchronized原始采用的是CPU悲观锁机制,即线程获得是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。
Lock用的是乐观锁的方式,所谓乐观锁就是,每次不加锁而是假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制是CAS 操作(Compare and Swap)。ReentrantLock的源代码中,比较重要的获取锁的一个方式是compareAndSetState。这里其实就是调用CPU提供的特殊指令。
现代CPU提供了指令,可以自动共享数据,而且能够检测到其他线程的干扰,而compareAndSet()就用这些代替了锁定。这个算法称作非阻塞算法,即一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。
两种锁的性能对比
如果竞争资源不激烈,两者的性能是差不多的。
当竞争资源非常激烈时(有大量线程同时竞争),Lock相比synchronized减少了CPU唤醒线程开销,此时lock的性能要远远优于synchronized。在具体使用要根据业务场景进行适当的判断。
两种锁的用途区别
synchronized和Lock(ReentrantLock)在一般情况下区别不是很大,但是在非常复杂的同步应用中,请考虑使用ReentrantLock.
特别是遇到下面2种业务需求的时候。
1.某个线程在等待一个锁的控制权的这段时间需要中断
2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程
3.具有公平锁功能,每个到来的线程都将排队等候
第一种情况,ReentrantLock的lock机制有2种,忽略中断锁和响应中断锁,比如A、B两个线程去竞争锁,A线程得到了锁,B线程等待,但是A线程处理时间太长,一直不返回,B线程可能会等不及了,想中断自己,不再等待这个锁了,转而去处理其他的事情。这个时候ReentrantLock提供了两种机制:可中断/可不中断
第一: B线程中断自己(或别的线程中断它),但是ReentrantLock不去响应,继续让B线程等待(synchronized就是如此)
第二:B线程中断自己(或者别的线程中断它),ReentrantLock处理了这个中断,B线程不再等待这个锁,彻底放弃。
ReentrantLock的忽略中断锁和响应中断锁
ReentrantLock中的lockInterruptibly()方法使得线程可以在被阻塞时响应中断,比如一个线程t1通过lockInterruptibly()方法获取到一个可重入锁,并执行一个长时间的任务,另一个线程通过interrupt()方法就可以立刻打断t1线程的执行,来获取t1持有的那个可重入锁。
ReentrantLock的lock()方法或者Synchronized持有锁的线程是不会响应其他线程的interrupt()方法的,直到该方法主动释放锁之后才会响应interrupt()方法。
猜你喜欢
- 2024-12-26 Java高级:条件队列与同步器Synchronizer的原理+AQS的应用
- 2024-12-26 浅谈Java多线程与并发原理 java多线程并发调用接口
- 2024-12-26 Java 基础(四)集合源码解析 List java集合linkedlist
- 2024-12-26 异步 vs 同步:程序员必备的核心知识,理解这两者差异,你就是高手
- 2024-12-26 ArrayList 、 LinkedList、Vector的区别
- 2024-12-26 java面试基础题(实战后的总结) java面试必考300题
- 2024-12-26 synchronized底层细究(硬核) synchronized底层原理是什么
- 2024-12-26 为什么 95% 的 Java 程序员,都是用不好 Synchronized?
- 2024-12-26 100+道高频Java面试题 java面试高频知识点
- 2024-12-26 如何看到 synchronized 背后的“monitor 锁”?
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)