4种常用线程锁synchronized、ReentrantLock、Semaphore、AtimicInteger的特点,性能比较、使用场景

    一、背景介绍
    1、在进程中的同时运行多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,
    线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。
    2、在Java并发编程中,经常遇到多个线程访问同一个 共享资源 ,开发者必须考虑如何维护数据一致性,这就是Java锁机制(同步问题)的来源。

    二、四种锁
    1、synchronized 维护数据一致性、 在资源竞争不是很激烈的情况下 、可读性好
    synchronized实现的机理依赖于软件层面上的JVM,随着Java版本的不断升级而提高,1.6之后对其进行了很多优化(自适应自旋、锁消除、锁粗化、轻量级锁、偏向锁)
    注意:当线程通过synchronized等待锁时是不能被Thread.interrupt()打断的,所以设计时必须检查,防止死锁发生。在确定锁机制是当前多线程程序的性能瓶颈时,可考虑虑使用其他机制,如ReentrantLock等。

    2、ReentrantLock 可重入锁 锁可以被线程多次重复进入进行获取操作。 高并发量情况下使用ReentrantLock
    1)ReentrantLock 继承接口Lock 并实现了接口中定义的方法,除了能完成synchronized的工作外,还提供了响应中断锁、可轮询锁请求、定时锁等避免多线程死锁的方法。
    2)Lock实现的机理依赖于特殊的CPU指定,可以认为不受JVM的约束,并可以通过其他语言平台来完成底层的实现。在并发量小的多线程应用程序中,ReentrantLock与synchronized性能相差无几,
    但高并发量的条件下,synchronized性能会迅速下降几十倍,而ReentrantLock的性能却能依然维持一个水准。

    3)公平锁:锁的分配是公平的, 先对锁提出请求的线程会被分配到锁
    4)非公平锁:JVM 按随机、就近原则分配锁的机制。
    5)ReentrantLock在构造函数中提供了是否公平锁的初始化方式,默认为非公平锁。因为非公平锁实际执行的效率远远超过公平锁。
    6)ReentrantLock通过方法lock()与unlock()来进行加锁与解锁操作,与synchronized会被JVM自动解锁机制不同,ReentrantLock加锁后需要手动进行解锁。在finally 控制块中执行解锁操作。
           public static void main(String[] args) {
            Lock lock = new ReentrantLock();

            /**
             * 方式一
             */
            assert lock.tryLock(); //判断是否获取锁
            //事务操作
            lock.unlock();

            /**
             * 方式二
             */
            try {
                lock.lock();
                //事务操作
            } finally {
                lock.unlock();
            }
        }
    3、Semaphore
    1)互斥是进程同步关系的一种特殊情况,相当于只存在一个临界资源,因此同时最多只能给一个线程提供服务。在实际复杂的多线程应用程序中,可能存在多个临界资源,
    这时候我们可以借助Semaphore信号量来完成多个临界资源的访问。
    2)Semaphone.acquire()方法默认为可响应中断锁,与ReentrantLock.lockInterruptibly()作用效果一致,也就是说在等待临界资源的过程中可以被Thread.interrupt()方法中断。
    除了方法名不同之外,使用方法大致相同。Semaphore也提供了公平与非公平锁的机制
    3)释放锁的操作也必须在finally代码块中完成。通过acquire()与release()方法来获得和释放临界资源。

    4.AtomicInteger
    1)首先说明,此处AtomicInteger是一系列相同类的代表之一,常见的还有AtomicLong、AtomicLong等,他们的实现原理相同,区别在与运算对象类型的不同。通过相关资料显示,通常AtomicInteger的性能是ReentantLock的好几倍。
    2不激烈情况下,性能比synchronized略逊,而激烈的时候,也能维持常态。激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。但是其有一个缺点,就是只能同步一个值,
    一段代码中只能出现一个Atomic的变量,多于一个同步无效。因为他不能在多个Atomic之间同步。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值