AQS同步组件

Posted wcgstudy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AQS同步组件相关的知识,希望对你有一定的参考价值。

java中锁主要分为两类: 1、 synchronized 关键字修饰的锁   2、 在同步容器JUC中 ReentrantLock(可重入性) 关键字修饰的锁

ReenTrantLock 和 synchronized 的区别: 

    1、可重入性 ,两者都是一样的,当有线程进入锁,计数器就加1,当计数器为0的时候,释放锁  

    2、 锁的实现 ,Synchronized 锁是基于jvm实现的 ,而ReenTrantLock是基于JDK实现的

   3、性能的区别 ,在synchronized进行性能优化之后,两者之间的区别是很小的,更建议使用synchronized,因为实现起来更为简单

    4、 功能的区别:  synchronized使用起来更加的方便和便捷,是由JVM实现加锁的,而reenTrantLock是需要通过代码实现加锁机制的 ,在锁的细粒度和灵活性方面reentrantLock是由于Synchronized的

   ReenTrantLock独有的功能: 

     1、 ReenTrantLock 可以指定是公平锁还是非公平锁 ,synchronized只能是非公平锁 ,所谓的公平锁就是先等待的线程先获得锁

      2、提供了一个condition类,可以实现分组唤醒需要唤醒的线程

    3、 提供了能够中断等待锁的线程的机制,lock.lockinterruptibly

ReenTrantLock 代码示例:  

   

package MyStudyTest.LOck;

import com.mmall.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@ThreadSafe
public class LockExample1 
    //总请求数
    private static int clientTotal = 5000;

    //总的并发请求数
    private static int threadTotal = 200;

    private static int count = 0;

    private final static Lock lock = new ReentrantLock();
    public static void main(String[] args) throws InterruptedException 
        //创建一个动态可变长线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        CountDownLatch countDownLatch = new CountDownLatch(clientTotal) ;
        Semaphore sema = new Semaphore(threadTotal);

        for (int i =0; i<clientTotal; i++ )
            executorService.execute(()->
                try 
                    sema.acquire();
                    add();
                    sema.release();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                finally
                    countDownLatch.countDown();
                
            );
        
        countDownLatch.await();
        executorService.shutdown();
        log.info("count:", count);
        
    private  static void add() 
        lock.lock();
        try 
            count++;
        finally
            lock.unlock();
        
    

    

关于ReenTrantLock 中一些方法的使用: (提供了很多线程操作的函数 )

    1、 trylock ()    --: 仅当线程调用时锁定未被另一个线程调用的情况下才获取锁定

    2、lockinteruptibly : 只有当当前线程没有被中断的情况下,才获取锁定 ,如果线程中断了,就抛出异常

    ReenTrantReadWriteLock : 当没有任何读写锁的时候,才获取锁

   

 

 

 

以上是关于AQS同步组件的主要内容,如果未能解决你的问题,请参考以下文章

AQS的几个同步组件

详解AQS的7个同步组件

详解AQS的7个同步组件

AQS同步组件

多线程七 AQS

AQS 源码分析