400 028 6601

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

掌握之并发编程-3.锁-创新互联

掌握高并发、高可用架构

第二课 并发编程

从本课开始学习并发编程的内容。主要介绍并发编程的基础知识、锁、内存模型、线程池、各种并发容器的使用。

为武隆等地区用户提供了全套网页设计制作服务,及武隆网站建设行业解决方案。主营业务为成都网站建设、网站建设、武隆网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
第三节 锁

并发编程 并发基础 AQS Synchronized Lock

这小节咱们来学习并发编程中锁的知识。主要包括关键字synchronized、各种LockAQS的原理、以及各自的应用。

synchronized

可以修饰方法或者代码块

表示多个线程访问该方法或者代码块时要进行排队,串行的执行该方法或者代码块

执行效率低,但是它是并发编程容器的基础

分类 具体分类 被锁的对象 示例代码 说明
方法实例方法类的实例对象synchronized void methodA() {};
void methodB() {};
synchronized void methodC() {};
线程调用了同步方法,
别的线程可以调用非同步方法,
对于其他同步方法,必须该方法在执行完成后才能调用
不影响静态方法的调用(包括同步,非同步)
静态方法类对象static synchronized void methodA() {};
static void methodB() {};
static synchronized void methodC() {};
线程调用了同步方法,
别的线程可以调用非同步方法,
对于其他同步方法,必须该方法在执行完成后才能调用
不影响对象方法的调用(包括同步,非同步)
代码块实例对象类的实例对象synchronized(this) {}同上
class对象类对象synchronized(SynchronizedTest.class) {}同上
任意实例对象实例对象ObjectObject lock = new Object();
synchronized(lock) {}
只影响锁住的对象,而不影响类和类的实例对象
synchronized的实现机制

JAVA对象头Monitor是实现synchronized的基础。

  1. JAVA对象头,对于Hotspot虚拟机的对象头主要包含两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)

    • Mark Word,用于存储对象自身的运行时数据,如哈希码(Hash Code)、GC分代年龄、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳等
    • Klass Pointer,是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
  2. Monitor,是一种同步机制,即同一时刻只允许一个线程进入Monitor的临界区,从而达到互斥的效果。synchronized的对象锁,其指针指向的是一个Monitor对象的起始地址。每个对象实例都有一个monitor。由C++实现,其数据结构如下。

    ```C++
    ObjectMonitor() {
    _count = 0;
    _owner = NULL;
    _waitSet = NULL;
    _waitSetLock = 0;
    _EntryList = NULL;
    }

    其中,**_owner**指向持有ObjectMonitor对象的线程。当多个线程同时访问一段同步代码时,会把线程存放在锁的对象的**_EntryList**中。当某个线程获得对象的Monitor时,就会把*_owner*的值设置为当前线程,同时*_count*加1。如果线程调用**wait()**方法,就会释放当前持有的Monitor,*_owner*置为null,*_count*减1,并将该线程放入**_waitSet**中。当然,如果持有monitor的线程正常执行完毕,也会释放monitor,*_owner*置为null,*_count*减1。

对于加在代码块上的synchronized,其字节码是:一次monitorenter、两次monitorexit(含有一次编译器自动生成的异常处理的monitorexit);

对于加在方法上的synchronized,其字节码是:标识方法为ACC_SYNCHRONIZED

新特性

synchronized是一个重量级锁,相较Lock,比较笨重,不高效。在JDK1.6中,其实现过程引入了大量的优化,如自旋锁自适应自旋锁锁消除锁粗化偏向锁轻量级锁等技术来减少锁的开销。

锁的等级

依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态

Lock

Lock是一个接口,有以下方法。

public interface Lock {
    void lock();
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    void lockInterruptibly();
    Condition newCondition();
}

这里说下方法void lockInterruptibly()一个线程获得锁之后是不可以被interrupt()方法中断的,是不能中断正在执行中的线程的,只能中断阻塞过程中的线程lockInterruptibly方法允许当线程等待获取锁的过程中由其他线程来中断等待。

Lock 和 synchronized的区别与相同点

区别:

相同点:

ReentrantLock

可重入锁,是Lock接口的唯一实现类。

可重入锁:是指如果一个线程获得了一个对象的锁,那么它不需要再获取该对象的锁而可以直接执行方法。也就是锁的分配机制是基于线程来分配的,而不是基于方法调用的分配。

可中断锁:可以响应中断的锁。只有lockInterruptibly()方法的锁是可中断锁,lock()还是不可中断的

公平锁:指尽量以请求锁的顺序来获取锁。比如有多个线程在等待一个锁,当锁被其他线程释放时,最先请求锁的线程会获得该锁

非公平锁:无法保证锁的获取是按照请求锁的顺序进行的。可能导致某个或者一些线程永远获取不到锁

对于ReentrantLock,默认是非公平锁,但可指定为公平锁。

ReentrantLock lock = new ReentrantLock(true)

ReentrantLock中定义了两个内部类,一个是NotFairSync,一个是FairSync。当构造器参数为true时,表示创建公平锁,参数为false或者无参时,表示非公平锁。

ReadWriteLock
public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}

一个用来获取读锁,一个用来获取写锁。

ReentrantReadWriteLock

可重入读写锁,实现了ReadWriteLock接口。

多个线程同时进行读操作时,会使多个线程交替进行,从而提高读操作的效率。但是,如果有线程占用读锁,此时其他要获取写锁的话,就必须等待读锁释放后才可执行;如果有线程占用写锁,此时其他线程不管是要获取读锁或者写锁的话,都必须等待写锁释放。

Lock的实现原理

ReentrantLockFairSyncNotFairSync都继承了AbstractQueuedSynchronizer,并且真正lock()unlock()的实现过程都是在AQS中。

首先,AQS的数据结构是:一个表示锁状态的变量volatile int state,取值范围是 0 无锁、1 有锁;一个用于存储等待获取锁的线程的双向链表transient volatile Node headtransient volatile Node tail

其次,加锁流程NotFairSync.lock()是:

  1. 通过CAS去尝试获取锁:判断当前state是0的话表示无锁,然后把当前线程设置为独占执行线程,再修改state为1表示有锁
    掌握之并发编程-3.锁

  2. 如果第一步获取锁失败,那么执行acquire(1)(这是AQS的方法)

掌握之并发编程-3.锁

主要是三个方法:

掌握之并发编程-3.锁

掌握之并发编程-3.锁
下面借两张图(

获取锁的流程:

掌握之并发编程-3.锁

然后,解锁的流程是调用NotFairSync.release(),主要是对重入数量的调整。每次释放锁都只会对数量减1,直到state为0时表示锁释放完成。
掌握之并发编程-3.锁

Lock和synchronized的选择

根据CAS的特性,建议在低锁冲突的情况下使用Lock

在JDK1.6后,官方对synchronized做了大量的优化(偏向锁、自旋、轻量级锁等),因此在非必要的情况下,建议都使用synchronized做同步操作

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章题目:掌握之并发编程-3.锁-创新互联
文章网址:http://www.bluegullmedia.com/article/ppcoj.html

其他资讯

让你的专属顾问为你服务

0.0506s