这里我们分三块来解读学习:
同步方法思想
同步块思想
同步方法与同步块的区别
1. 同步方法思想
上面是我画的同步方法思想简化图,我们将每个对象类比喻为房子,对象类拥有的多个方法比喻为很多房间,有同步锁的方法比喻为有锁的房间(锁放在房间门口),没有同步锁的方法比喻为没有锁的房间,方法的调用者我们将其比喻为想要进入某个房间的人。想进入这些房间有一些规则必须遵守,这里可以比喻为家规吧。
规则:
- 没有锁的房间可以不用等待进入,而且可以容纳多人;
- 有锁的房间必须有钥匙才可进入,而且只可容纳一人;
- 对于有锁的房间,如果门口有钥匙则进入,如果没有,说明房间内有人,则排队等待拿到钥匙才可以进入;
- 从有锁的房间出来后,如果想要再次进入,必须归还钥匙之后,在门口重新排队等待钥匙。
2. 同步块思想
从包含的代码量来说,同步代码块比同步方法小。我们可以把同步代码块比喻成是没上锁房间里的多了一层带锁的内门。
带锁的内门可以由用户自定义其钥匙,你可以用本房的钥匙,你也可以指定用另一个房子的钥匙才能开,这样的话,你要跑到另一栋房子那儿把那个钥匙拿来,并用那个房子的钥匙来打开这个房子的带锁的内门。
记住你获得的那另一栋房子的钥匙,并不影响其他人进入那栋房子没有锁的房间。
3. 同步方法与同步块的区别
解析到这里,很多读者好奇的问了,同步块存在的意义?
我猜想原因有下面几点:
- 对Java程序来讲同步的部分很影响运行效率,而一个方法通常是先创建一些局部变量,再对这些变量做一些操作,如运算,显示等等;而同步所覆盖的代码越多,对效率的影响就越严重。因此我们通常尽量缩小其影响范围。如何做?同步代码块。我们只把一个方法中该同步的地方同步,比如运算。
- 同步代码块可以指定钥匙这一特点有个额外的好处,是可以在一定时期内霸占某个对象的key。比如前面说过的一种特殊情况,这个人想进入某个房间之后,不想要等待,立马进入另一个房间,这时就可以采取这种做法。
- 当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
当然,我们代码逻辑上有时会有这样的需求,在现实生活中对于公共的资源,暂时不用某个,可以先给他人用,可别采取同步块的做法哦。
简单总结:
其实同步方法和同步块都是锁的概念,不同的是同步方法是“外门”的锁,同步块是“内门”的锁,就好像我们去游乐场玩的时候排队一样,基本每个项目都是单个队列,但是中间有好几道栅栏。读者可以细细想想,其实我们说的同步方法和同步块的思想就在其中。