这张照片不比上一张好看吗?旋转?如果此时自旋锁拿不到锁,它不会立即进入阻塞状态,而是愿意等待一段时间。如果循环一定次数后仍无法获得锁,则进入阻塞状态,循环次数可以手动指定。自旋锁🌰有一天,我去家里买咖啡。服务员说很可惜,我面前的咖啡机坏了,正在维修。我不得不等了10分钟。正好没有什么急事,就在休息区等着等了10分钟(没干别的)。介绍的是自旋锁~(闲了一会儿)感觉浪费时间?如果您已经等了15分钟还没有修复,那么您可能不想再等了(15分钟是旋转等待设置的最长时间)。上面说自旋锁的循环次数是人为指定的,自适应自旋锁很强大。它不需要手动指定循环次数。它会自己判断循环多少次,每个线程可能循环的循环次数也不一样。如果线程之前获取过锁,或者经常获取锁,那么它自己判断再次获取锁的概率很大,循环次数会更大;如果线程之前没有获取过锁,那我就不确定了,怕耗cpu,循环次数会小一些。它解决了“锁竞争时间不确定”的问题,但并不一定代表它自己的设置就合适。自适应旋转锁🌰还不如去全家人在栗子面前等咖啡呢~如果等了5分钟没修好,目测10分钟也修不好,就不要再等了(循环次数少);等了10分钟,服务员说很抱歉,差不多了,再过一分钟就可以了。你不着急,你已经等了10分钟了,再等一会儿就好了(循环次数多)。这是自旋锁的简单代码实现:publicclassSpinLock{privateAtomicReferencecas=newAtomicReference();publicvoidlock(){Threadcurrent=Thread.currentThread();//使用CASwhile(!cas.compareAndSet(null,current)){//DOnothing}}publicvoidunlock(){Threadcurrent=Thread.currentThread();cas.compareAndSet(current,null);}}稍微分析一下~lock()方法使用了CAS,当第一个线程A获取锁时,能够成功获取,就不会进入while循环;如果此时线程A不释放锁,另一个线程B再次获取锁,就会因为不满足CAS而进入while循环;然后线程B会不断判断CAS是否满足,直到A线程调用unlock方法释放锁,才能获取到锁。主要有以下问题:如果一个线程持有锁的时间过长,会导致其他等待获取锁的线程进入循环等待,消耗CPU。使用不当会导致CPU使用率过高。公平性本身并不能保证,即等待时间最长的线程不能先获取到锁。不公平的锁会出现“线程饥饿”的问题。无法保证重入。基于自旋锁,可以实现具有公平性和可重入性的锁。后面几个有时间再详细说吧~自旋锁Vs阻塞锁Chestnut~去一家人气餐厅吃饭,走到门口一看,门口的座位都坐满了人...怎么了...服务员说,你先拿号吧~扫描小票上的二维码,关注我们,轮到你的时候,服务号里会有提示~(很熟悉,是不是不是吗?)然后你先拿号逛逛我去了小店,轮到你的时候,我手机收到一条服务提示信息,轮到你了~可以进店了你这时候再去。这就是阻塞过程~自旋呢?也就是你不做其他事情就在那里等着,就像去超市结账一样。如果你走开,没有人会通知你。只能重新排队。到共享资源)。这里有一个插曲:阻塞或唤醒一个Java线程需要操作系统切换CPU状态才能完成,而这个状态转换需要处理器时间。我们来看看自旋和阻塞的对比~锁态锁主要有四种只升不降的状态:“无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态”。其实这四种状态并不是Java语言中的锁,而是Jvm为了提高锁的获取和释放效率而做的优化(使用synchronized时)。他们会随着激烈的竞争而逐步升级,而且是不可逆转的升级。升级过程是这样的:偏向锁->轻量级锁->重量级锁关于无锁~如果一个方法不涉及共享数据,自然不需要任何同步措施来保证正确性,所以自然会有一些代码线程安全的。它不锁定资源,所有线程都可以访问和修改同一个资源,但同时只能有一个线程修改成功。CAS算法就是compareandswap(比较和交换),这是一种著名的无锁算法。详细对比一下状态吧~明明知道要栗子,经常去饭店坐同一个位子吃。老板已经记住你了。坐稳那个位子,这个位子就是你的“偏向锁”,一次只有你一个线程可以使用。有一天你去的时候,店里满了,你的座位被别人占了,你只能等待(进入竞争状态),然后那个座位就会升级为“轻量锁”。如果那个位子特别好(靠窗的风景最好,还能隔江赏月~)每次到的时候,其他几个人也会抢那个位子,如果你不坐那里,你不吃>_<当时那个座位升级成了“重量级锁”。容易理解吗?共享还是独占?狮子集体喝水😄河流是共享资源~狮子想独享资源,专业的说说概念吧~(请点手机看大图~)还有栗子~各拜拜群的所有成员需要一起填写每周报告表。如果大家都打开,可以加写锁,就是你在写的时候,别人不能修改。这是一个独占锁(写锁);但是这个Everyone可以同时打开这个表单,看到这个表单的内容(读数据),而这个修改数据的人可以给这个表单加一个共享锁,那么这个锁就是一个共享锁。小总结整理一下Java中的各种锁概念,写一些自己的理解。还有很多基础的,比如Java对象头,对象模型(都是比较基础的),锁优化,各种锁代码实现。等等,稍后补充。公众号很多,高水平的文章很多,需要理解和实践的太多了。好了~说累了,我要先休息~