Java中实现锁的方式有哪些?详细介绍

XIAO 2020-04-14 12:56:45 java常见问答 7546

其实要是作为程序员的话,应该会经常听到,甚至也曾经实现过有关在java中的锁机制,那么,你现在还记得在java中去实现锁的方式有哪些吗?记得当然更好,不记得也没关系,就当一起复习一遍吧。

首先我们来看看Java锁的种类。按照抢占线程的调度方式来分:公平锁和非公平锁。公平锁呢,是指多个线程按照申请锁的顺序来获取锁。非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,非公平锁由系统根据情况进行调度,一般更能适应需求。

按照同一线程是否能重新进入同一锁来分:可重入锁和不可重入锁两种。可重入锁,就是说同一个线程可多次进入同一把锁, 可重入就意味着:线程可以进入任何一个它已经拥有的锁所同步着的代码块。

第一个线程执行print()方法,得到了锁,使lockedBy等于当前线程,也就是说,执行的这个方法的线程获得了这个锁,执行add()方法时,同样要先获得锁,因不满足while循环的条件,也就是不等待,继续进行,将此时的lockedCount变量,也就是当前获得锁的数量加一,当释放了所有的锁,才执行notify()。如果在执行这个方法时,有第二个线程想要执行这个方法,因为lockedBy不等于第二个线程,导致这个线程进入了循环,也就是等待,不断执行wait()方法。只有当第一个线程释放了所有的锁,执行了notify()方法,第二个线程才得以跳出循环,继续执行。

那么相反就是不可重入锁。ReentrantLock和synchronized都是一个可重入锁。可重入锁的一个好处是可一定程度避免死锁。

按照锁能否被多个线程占有来区分: 共享锁和独享锁。共享锁是指该锁可以被多个线程所持有;独享锁是指该锁一次就只能被一个线程所持有。

从看待线程同步的态度分:乐观锁和悲观锁。悲观锁,顾名思义,像悲观的人一样,每次都认为别人会修改,所以都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。synchronized关键字的实现就是悲观锁。乐观锁,像乐观的人一样,每次都认为别人不会修改,所以不会上锁,只要在更新的时候会判断一下在此期间别人有没有去更新这个数据。CAS(Compare and Swap 比较并交换)实现的就是乐观锁。

从synchronized实现的锁升级阶段来分:偏向锁,轻量级锁,重量级锁。偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁(只需与对象头中线程ID比较一致)。降低获取锁的代价(大部分并发场景都是这种情况)。 轻量级锁是指当锁是偏向锁的时候,且偏向锁的进程还持有该对象时,锁被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程则通过自旋的方式尝试获取锁。该方式就是循环获取的意思,线程一直在cpu执行中,不会阻塞,也没有线程的上下文切换,短时间如果能再次获得锁,那么这种方式能提高性能。重量级锁是指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续,因为不能一直占用cpu的进程。

那么以上就是有关java中锁实现的一些方式了,还想了解java一些知识问答,记得关注本站消息。