可重入锁
1.LongAdder的本质
里面是一个数组,假设长度为4,当有1000个线程的时候,250个线程分别占用一个,最后相加,就可得到递增总数
2.ReentrantLock可重用锁
可重入锁:可重入锁又称递归锁,是指同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象得是同一个对象),不会因为之前已经获取过锁还没有释放而阻塞。
可重入的标识是指,有一个state变量,当state=0时,表示该对象没有加锁。当state》=1时,表示已经加锁。如果线程是同一个,会通过cas对state变量进行+1.这也是可重入的概念。
他的作用和synchronized差不多,可以完全替代,加锁的时候用lock.lock(),解锁的时候lock.unlock(),一般放到finally中去执行。
public class Test6 { Lock lock = new ReentrantLock(); void m1() { try { lock.lock(); for (int i = 0; i < 10; i++) { Thread.sleep(1000); System.out.println(i); } }catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
但是,ReentrantLock有比synchronized好的一些地方,比如,可以使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行,并可以根据返回值来判断是否锁定。
void m2(){ boolean locked = false; try { locked = lock.tryLock(5, TimeUnit.SECONDS); }catch (InterruptedException e) { e.printStackTrace(); }finally { if (locked)lock.unlock(); } }
其次,ReentrantLock可以使用lock.lockInterruptibly()上锁,但是这个上锁可以被打断,不用一直等待锁的释放,用threadB.interrupt()。
https://blog.csdn.net/az44yao/article/details/105134306
最后,ReentrantLock即可以是公平锁也可以是非公平锁,默认为非公平锁。当为公平锁是,线程来了之后,会先判断队列中是否有线程已经在等待,如果有等待,就会继续向后排队,如果不公平,上来就是竞争锁。
3.AQS的本质
AQS的本质是由volatile和cas组成,有一个用volatile修饰的state变量,当为1时,表示线程被占用,0表示没有占用。在赋值这块使用了compareAndSet修改state的值等,本质就是CAS。当线程竞争失败时,AQS有一个双向队列,会将该线程封装成一个NODE节点,然后放入队列尾部进行排序。
https://www.cnblogs.com/fsmly/p/11274572.html
浙公网安备 33010602011771号