可重入锁


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