文章目录
一、使用方法
synchronized (T1.class) {
i++;
}
二、名词解释
1.管程(monitor)
小括号内的对象称为管程,上诉例子,T1.class就是管程。
2.临界区(cirtical section)
大括号内的代码块称为临界区。
临界区大,语句多,叫锁的粒度粗,反之锁的粒度细;
三、锁升级概念
在jdk1.6以后,jdk对synchronized进行了优化。引入了锁升级。
1.偏向锁(只做标记,把自己的线程id放到markword中)
故事比喻:有个厕所,没什么人用,每天就张三一个人进去几次,张三进去就把自己名字挂在门上,出来把名字放下来。
2.轻量级锁(自旋锁)。每个线程在自己线程栈中生成一个LR(Lock Record,锁记录),然后把LR贴到markword中,cas贴上去的标识抢到锁,其他线程继续CAS。
故事比喻:有一天,李四也发现了这个厕所。于是张三李四虽然大部分时候都能过来就用,但也会偶尔会争抢锁,张三在里面上的时候李四就在外面每隔一会就来看看张三出来了没。
3.重量级锁(OS,markword中记录的是objectMonitor)
故事比喻:人慢慢多了起来,厕所太多人用了,大家只能排队等待。
四、用户态和内核态
内核态是指只有操作系统内核才能调用的指令,如删除系统文件,直接操作内存物理空间之类的敏感操作。
用户态是指用户程序能调用的指令,比如操作虚拟内存,比如向内核态申请打开socket。
偏向锁和轻量级锁是用户态锁,重量级锁是内核态锁
五、和Lock的区别
其实原理都差不多,就是用一个同步队列,锁发生竞争时往同步队列里塞线程。解锁时从同步队列唤醒线程。
不同点:
1.synchronized是在内核态实现的。Lock是在用户态实现的。
2.Lock上锁解锁可以自己代码控制(更自由,锁类型也更多),synchronized只能使用代码块。
3.synchronized的管程可以是任何对象,Lock只能是Lock对象。
推荐还是用synchronized,因为引入锁升级优化后不比Lock慢多少了
六、乐观锁与悲观锁
乐观锁:认为大部分时候没有锁竞争,通常用CAS实现
如AtomicInteger,就是用乐观锁实现的
悲观锁:认为大部分时候都需要竞争,通常用同步队列排队实现,如Lock,就是用悲观锁实现的