`
annan211
  • 浏览: 456578 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java 锁分离

 
阅读更多

    读写锁思想的延伸就是锁分离。读写锁根据读写操作功能上的不同,进行了有效的锁分离。依据应用程序的功能特点,使用类似的分离思想,也可以对独占锁进行分离。
一个典型的应用就是java.util.concurrent.LinkedBlockingQueue.

    在LinkedBlockingQueue的实现中。take()和put()函数分别实现了从队列中获取数据和往队列中增加数据的功能。虽然这两个操作都是对当前队列进行修改操作,但由于LinkedBlockingQueue 是基于链表实现的,因此这两个操作分别对应这链表的前端和尾端,从理论上讲,这两个操作并不冲突。

   如果使用独占锁,则要求在这两个操作进行时获取独占锁,那么这两个操作就不可能实现真正意义上的并发,激烈的锁竞争从而 影响系统性能。
 
   在jdk中,并没有使用这种方式,取而代之的是 两把不同的锁分离了take()和put()操作。



  
      /** Lock held by take, poll, etc */
    private final ReentrantLock takeLock = new ReentrantLock();

    /** Wait queue for waiting takes */
    private final Condition notEmpty = takeLock.newCondition();

    /** Lock held by put, offer, etc */
    private final ReentrantLock putLock = new ReentrantLock(); 
   


 
    以上代码定义了 takeLock 和 putLock ,他们分别对应着 take() 和 put()操作,take()和put()是相互独立的,take(0和take()竞争锁,put()和put()竞争锁。
 


 
       public E take() throws InterruptedException {
        E x;
        int c = -1;
        final AtomicInteger count = this.count;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lockInterruptibly();// 不允许同时读取锁
        try {
            try {
                while (count.get() == 0)
                    notEmpty.await();
            } catch (InterruptedException ie) {
                notEmpty.signal(); // propagate to a non-interrupted thread
                throw ie;
            }

            x = extract();
            c = count.getAndDecrement();
            if (c > 1)
                notEmpty.signal();
        } finally {
            takeLock.unlock();
        }
        if (c == capacity)
            signalNotFull();
        return x;
    }
   


  
public void put(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        // Note: convention in all put/take/etc is to preset
        // local var holding count  negative to indicate failure unless set.
        int c = -1;
        final ReentrantLock putLock = this.putLock;
        final AtomicInteger count = this.count;
        putLock.lockInterruptibly();//不允许同时修改锁
        try {
            /*
             * Note that count is used in wait guard even though it is
             * not protected by lock. This works because count can
             * only decrease at this point (all other puts are shut
             * out by lock), and we (or some other waiting put) are
             * signalled if it ever changes from
             * capacity. Similarly for all other uses of count in
             * other wait guards.
             */
            try {
                while (count.get() == capacity)
                    notFull.await();
            } catch (InterruptedException ie) {
                notFull.signal(); // propagate to a non-interrupted thread
                throw ie;
            }
            insert(e);
            c = count.getAndIncrement();
            if (c + 1 < capacity)
                notFull.signal();
        } finally {
            putLock.unlock();
        }
        if (c == 0)
            signalNotEmpty();
    }




  概念太多反而不易于理解,这里简单说下 锁分离和分段锁。
  我们以ConcurrentHashMap 这种数据结构来分析,锁分离机制,就是把一个HashMap 分成很多个segement,对每一个segement的写操作上锁。他的get()操作是没有锁的,具体思想就是把每个hash槽中的链表的头节点置成final的。对hash槽中链表操作,只能从头部去处理。这样就不会有读不一致的情况出现。这个原理,最好还是看源码,比较清晰。
分享到:
评论

相关推荐

    多线程(22)读写锁分离模式1

    读写锁分离模式允许多个读取操作并行执行,而写入操作则保持互斥,从而提高系统的整体性能。Java中提供了`java.util.concurrent.locks.ReadWriteLock`接口来支持这种模式,但在本案例中,我们将模拟实现一个读写锁来...

    Java并发篇乐观锁,悲观锁,自旋锁

    - **锁分离**:如ReadWriteLock,读写操作分别用不同的锁,提高并发性。 - **锁粗化**:避免对同一锁的频繁请求和释放,将多个连续的同步块合并。 - **锁消除**:编译器自动检测无锁化的可能,消除不必要的锁。 ...

    java锁机制详解.pdf

    Java锁机制是多线程编程中的关键概念,用于控制对共享资源的并发访问,以确保数据的正确性和一致性。在Java中,主要的锁机制包括synchronized关键字和Lock接口(如ReentrantLock)。这里我们将详细讲解这两种锁以及...

    java多线程、锁的教程跟案例

    二、Java锁机制 1. **内置锁(显式锁)** - ReentrantLock(可重入锁):提供与synchronized相似的功能,但更灵活,支持公平锁、非公平锁,以及可中断和定时尝试获取锁。 - ReadWriteLock(读写锁):...

    java中的锁

    4. 锁分离:读写锁(ReentrantReadWriteLock)实现了一种分离锁机制,允许多个线程同时读取,但写入时独占资源,提高并发性能。 5. 偏向锁与轻量级锁:JVM对内置锁进行了优化,当锁竞争不激烈时,使用偏向锁或轻量...

    java 锁 Lock接口详解.docx

    Java中的锁机制是多线程编程中至关重要的概念,用于控制对共享资源的并发访问。在Java 1.5版本后,引入了`java.util.concurrent.locks`包,其中的`Lock`接口作为同步机制的新选择,弥补了`synchronized`关键字的一些...

    Java concurrency之锁_动力节点Java学院

    `ReentrantReadWriteLock`是其具体实现,提供读写分离的锁管理。 3. **AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer**:AQS(AbstractQueuedSynchronizer)是很多并发...

    java编程的生产者消费者同步锁线程测试

    此外,Java 5引入了`java.util.concurrent.locks`包,提供了更细粒度的锁控制,如`ReentrantLock`,它具有可中断、公平性和锁分离等特性。 接下来,我们讨论"生产者消费者问题"。在这个模型中,通常会有一个队列...

    java并发规范(线程及锁).docx

    9. **分离锁与分散锁**:尽可能选择分离锁(如`ReentrantReadWriteLock`)或无锁数据结构(如`ConcurrentHashMap`),以提高并发性能。 10. **基于`ThreadLocal`避免锁**:在某些情况下,使用`ThreadLocal`可以避免...

    Java的两种读写锁介绍

    在Java并发编程中,读写锁是用于优化多线程访问共享资源的一种机制,它可以提高对数据的并发访问效率。本文将深入探讨Java中的两种读写锁:ReentrantReadWriteLock和StampedLock,并分析它们的工作原理、特点以及...

    Java 锁粗化与循环问题

    Java 锁粗化与循环问题 Java 锁粗化是指合并使用相同锁对象的相邻同步块的过程,以减少锁开销。Hotspot 虽然进行了锁粗化优化,但是在循环中是否也可以进行这种优化?通过实验和分析,我们可以看到 Hotspot 的优化...

    java进阶提高学习教程-14锁机制.pptx

    读写锁维护一对读锁和写锁,通过读和写锁的分离,提升并发性能。Java 中的 ReentrantReadWriteLock 类是 ReadWriteLock 接口的实现类。 CAS CAS 是 Compare And Swap,即比较和交换。CAS 使用一个期望值与一个变量...

    java笔面试试题题库

    - Struts:MVC框架,负责视图和控制器的分离。 - Spring:全面的轻量级框架,包含IoC(控制反转)、AOP(面向切面编程)、事务管理等。 - Hibernate:ORM(对象关系映射)框架,简化数据库操作,提供对象级别的...

    多线程的使用与线程锁的两种实现

    - 分离的锁获取和条件变量:ReentrantLock支持多个条件变量,每个条件变量都有自己的等待队列。 三、线程通信 Java提供了一些线程通信的工具,如wait(), notify()和notifyAll(),它们都与对象的监视器(monitor)...

    基于JDK源码解析Java领域中的并发锁之设计与实现.pdf

    典型的实现如ReentrantReadWriteLock,它提供了分离的读锁和写锁,提高了并发性能。 六、自定义API操作的设计与实现 开发者可以根据需求自定义锁和同步机制,利用AQS提供的基础同步器构建满足特定需求的并发工具类...

    java后台;java后台

    Java提供了内置的线程类和锁机制,如synchronized关键字、volatile变量、ThreadLocal等,来确保并发环境下的数据安全。 6. **RESTful API设计**: REST(Representational State Transfer)是一种网络应用的设计...

    java并发编程2

    - **读写锁模式** 通过分离读取和写入权限,允许多个读取线程同时进行,但写入时互斥。 - **双检锁/双重校验锁(DCL)模式** 用于安全地初始化单例对象,确保在多线程环境下正确创建。 5. **并发集合** - **线程...

    java并发编程实战(英文版)

    - **锁分离**:讲解锁分离技术,以及如何通过减少锁的竞争来提高程序性能。 - **无锁编程**:探讨无锁编程的基本原理和技术细节,包括使用原子变量进行并发控制的方法。 - **并发集合**:详细介绍Java提供的各种并发...

Global site tag (gtag.js) - Google Analytics