如何给女朋友解释清楚Synchronized的三种应用方式

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/HJsir/article/details/81567738

事情的起因是这样的,女友面试的时候被面试官问到了一个问题就是关于synchronized的几种应用方式,她没理解,于是我决定给他理一理,就有了这篇博客。

synchronized的三种应用方式

  1. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
  2. 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
  3. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定实例对象的锁。

以上是上面三种方式的一个简单说明,特别注意实例和类对象,实例可以new很多个,但是类对象只有一个。
那么如何理清这三者之间的关系呢,我们用打比方的形式来讲解。情景是这样的:

人:线程
小区:表示该类
很多不锁门的房子:实例对象
房子里的房间:没锁的房间代表没带synchronized的方法,锁了的表示带关键字的方法。钥匙在门口只有一把
房子里带锁的盒子:表示synchronized锁住的代码块,钥匙可以是房门钥匙,也可以指定其他钥匙。
一个公共车库:存贮该类的静态方法
车库里的车位:带锁车位表示带有synchronized关键字的静态方法,没带锁表示没有此关键字的静态方法,钥匙在门口只有一把。


需注意的是,一个房子里只有一把钥匙,能开所有房间。一个车库里也只有一把钥匙,能开所有车位。

有了上述描述,于是我们来复现部分情景:
1、一堆人进入了房间但是由于钥匙只有一把,甲同学先拿到钥匙,所以后面想进入其他房间的人必须等他用完钥匙锁好门出来了才行。

这段话意思就是:其他线程等待持有对象锁释放才能进入该实例对象的其他同步方法

2、甲同学在房子里玩腻了以后出来了,然后把钥匙忘人堆里一扔,被乙同学抢到了,乙同学于是拿着钥匙去了房间

这段话意思是:持有锁被释放后其他线程需要竞争
3、甲同学扔完了钥匙以后,乙同学拿着钥匙马上进了房间,然后甲同学没有闲着,去其他隔壁没有锁门的房间玩了。

这段话意思是持有该对象的锁进入该对象带有synchronized方法后,不影响其他线程进入该实例对象其他没synchronized的方法。

4、此时甲同学在该房间里发现一个盒子,他想要开这个箱子,盒子上指定了需要房门钥匙打开,但是手里没钥匙,于是把等乙出来把钥匙抢了过来,开了盒子。

这段话意思是:你可以进入没带synchronized关键字的方法,但是同步代码块想要进入就得要持有该代码块指定的对象锁。

5、用钥匙打开了盒子后,甲觉得其他房间也应该有盒子,于是去了其他没锁门的房间,发现有个房子确实有,但是盒子上面写着要用隔壁房子的钥匙才能打开,无奈,他又去隔壁房子抢了把钥匙才打开盒子。

这段话的意思就是:代码块可以指定持有其他对象锁才能进入,其实就是我们用同步代码块时候synchronized(…){..}中括号里指定的。

6、甲玩腻了,把房门钥匙扔给了丙,丙进入了房间,而甲决定去车库里开辆跑车来玩,于是去车库刚好拿到了钥匙,打开了带锁车位里的兰博基尼,出去玩了。

这段话的意思是:持有该实例对象锁与持有类锁是两个互不干扰的,可以看到丙在房子里玩,而甲开了车子出去了。意味着其他线程持有哪种锁就可以进入相应的方法,而且还可以同时持有。

总结

类似的其他情景我们都可以想象出来,如果当面试官问你关于这些问题的时候,你就用这个比喻来推理。比如面试官问你synchronize锁代码块,没有锁方法, 其他线程能进入该方法么,其实就相当于问你一个没锁门的房子其他人能进来么?答案当然是能进来。类锁和对象锁是相互不影响的,你可以同时持有,进入某个方法只要你持有该锁就行了。

欢迎补充和纠错!

展开阅读全文

没有更多推荐了,返回首页