可重入锁
1.LongAdder的本质
里面是一个数组,假设长度为4,当有1000个线程的时候,250个线程分别占用一个,最后相加,就可得到递增总数
2.ReentrantLock可重用锁
他的作用和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