以玄幻小说的角度说说Java中的锁

前言

      我们在高并发,多线程的场景中,为了确保某一共享变量只被同一线程访问的时候,通常会采用锁的机制,而锁的通常使用synchronized关键字是最为简单粗暴的,那这个关键字原理又是怎样的呢,里面会有锁的升级是怎样的呢,我这段内容前前后后花了很长时间,才形成自己的理解,现在我用玄幻小说的角度来加深一下理解

背景

      在某个修炼门派,里面有三个精英弟子,分别是小A,小B,小C,他们三人因优异表现,经长老许可,三人可以在练功房修炼门派最高心法,但是这个心法有个坏处,只能一人参阅修炼。为防止纷争,必须在练功房,由守护长老看守,打上印记之后方可修炼。

偏向锁场景

      一开始的时候,小A比较勤快,在小A第一次来的时候,长老就在心法上面加了个小A的印记,这样小A每次来的时候,长老直接确认一下印记,就可以把心法交给小A,小A修练完以后,还给长老。我们可看到,这个阶段,长老很轻松,只要打一次印记,其他时候,就确认一下身份,其他时候,他还是很轻松的。

    在jdk1.6以后中,当只有一个线程A访问synchronized同步块里面的时候,这个时候,就把锁对象的对象头里面Mark Word的部分设定成偏向锁,并指向那个线程A就好了,后面线程A再次访问的时候,几乎是直接访问同步块里面的内容,这样会省略很多资源。

轻量级锁的场景

      当小A修炼的很轻松的时候,小B和小C就感觉不爽了,凭啥你一个人修炼啊,我们也是精英弟子。这样他们也参与了心法的修炼,心法就出现了争夺。一开始的时候,大家还是比较有秩序的。小A走了之后,小B修炼,小B走了之后,小C修炼。这个时候,长老就不能一直打酱油了。当小A来的时候,长老会给心法打上小A的印记,然后把心法交给小A。等小A修炼好了,把心法还给长老,小B来的时候,长老先确认心法里面的印记,再把心法里面的印记抹去,打上小B的印记,把心法交给小B,小B拿到心法以后,他也可以修炼。小B走了,小C来了,长老再操作一遍。我们发现,这个时候,长老就有点忙碌了,不仅要换标记,还要验证身份,这个时候,他会怀念之前的日子。

      之前,同步代码块里面只有线程A访问,当线程B也来访问的时候,原先的偏向锁就不再适用了,因为出现了交替。这个时候,偏向锁会膨胀成轻量级锁,锁对象的对象头标记会换,同时会把这个锁交给多个线程,只是这种情况比较和谐,大家都是按照秩序来的。线程之间实际无阻塞,也不涉及内核态用户态的切换。

重量级锁的场景

      当等大家修炼了一段时间,开始变得贪心了,都想多修炼一会儿,都想早修炼,所以就开始三个人都找长老申请修炼,长老呢,功力深厚,就把印记给最早的人,让最早的人先修炼,同时用定身术,定住其他两个人。等修炼中的人等修炼好了,长老会解开定身术,同时按照他定制的规则,给其中一个人修炼,另外一个人则继续定住。等心法重新空闲下来以后,长老才会解开定身术,打上印记让他修炼。这个时候,我们发现长老就变得比较烦了,不仅要处理印记,还得核验身份,还得判断心法该交给谁,更令他无语的是他得使用比较损耗真力的定身术。

      所以在外面java中,一旦到了synchronized同步块开始出现资源竞争的时候,轻量级锁就会膨胀成重量级锁。这个时候,需要阻塞等待的线程,等锁资源释放的时候,得重新唤醒阻塞线程,这个过程会出现内核态用户态的切换,造成系统资源的浪费,如果并发量很高的时候,这个切换的成本就很高,造成资源响应慢

总结

      由上面可知,外面的一个synchronized关键字,jdk的大咖们还是给了很多有利的支持,虽然现在很多高并发高响应的系统不推荐这个关键字,但是只要我们掌握好使用技巧,还有场景,我觉得还是可以通过这个关键字,来给我们系统带来安全保证。

你可能感兴趣的:(以玄幻小说的角度说说Java中的锁)