厦门网站建设价格,互联网产品运营是做什么的,网站建设与管理教案,网站开发应用技术专业java中的锁java添加锁的两种方式#xff1a;synchronized#xff1a;关键字 修饰代码块#xff0c;方法 自动获取锁、自动释放锁Reentrantlock#xff1a;类 只能修饰代码块 手动加锁、释放锁java中锁的名词一些锁的名词指的是锁的特性#xff0c;设计#xff0c;状态synchronized关键字 修饰代码块方法 自动获取锁、自动释放锁Reentrantlock类 只能修饰代码块 手动加锁、释放锁java中锁的名词一些锁的名词指的是锁的特性设计状态并不是都是锁。 乐观锁实际是没有锁认为并发操作不加锁的方式实现是没有问题的每次操作前判断CAS自旋思想是否成立是一种不加锁实现乐观锁和悲观锁不是指具体的什么类型的锁可以将其看做一种解决并发同步问题的角度。悲观锁认为并发操作肯定会有问题的所以必须加锁是加锁的实现。总结乐观锁适合读操作多的场景悲观锁适合写操作多的场景。可重入锁又名递归锁是指在同一个线程在外层方法获取锁得时候可以获取到内部其他同步方法的同步锁。读、写锁ReentrantReadWriteLock支持读写加锁如果都是读操作加锁这个读锁可以被多个读操作的线程共享如果一旦有写操作加写锁读写互斥分段锁并非一种实际的锁是一种思想将锁的粒度拆分提高效率如ConcurrentHashMap自旋锁并非一种实际的锁是以自旋的方式重新获取锁自己重试当线程抢锁失败就重试几次成功了就继续抢不到则线程阻塞共享锁锁可以被多个线程所持有共享如读写锁中的共享锁独占锁是互斥锁同一时间该锁一次只能有一个线程持有如synchronized公平锁按照请求锁的顺序获取锁就是可以根据线程的先来后到公平的获取锁例如ReentrantLock可以实现公平锁非公平锁没有先来后到谁抢到谁获得执行权ReentrantLock也可以实现非公平锁Synchronized是非公平锁。Synchronized锁实现Synchronized锁是依赖底层编译后的指令来控制的需要我们提供一个同步对象来记录锁状态。java中Synchronized通过在对象头设置标记记录锁状态多个线程需要是同一个锁对象在定义线程类时创建一个static的对象作为锁对象即可才可以实现加锁控制的目的达到获取锁和释放锁的目的。在Synchronized锁的底层实现中提供锁的状态用来区别对待这个锁的状态存储在同步锁对象的对象头中有一个区域叫Mark Word中存储。这几个状态是根据条件不断攀升的目的还是优化如下无锁状态偏向锁状态一直是一个线程访问 记录线程的id快速访问轻量级锁状态当锁状态为偏 向锁时又继续有其他线程来访问此时升级为轻量级锁没有获取到锁的线程不会阻塞而是继续不断尝试获取锁重量级锁状态当锁状态为轻量级锁时线程自旋达到一定的次数时进入阻塞状态锁状态升级为重量级等待操作系统调度再次普及一下对象头的概念对象的结构实例对象在内存中的布局分为三个区域对象头、实例数据、对齐填充。对象头对象头中有一块叫Mark Word的区域用于存储自身的运行时数据如哈希码HashCode、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID。实例数据实例数据部分是对象真正存储的有效信息也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的还是在子类中定义的都需要记录起来。对齐填充第三部分对齐填充并不是必然存在的也没有特别的含义它仅仅起着占位符的作用。在介绍其他锁之前先要认识AQSAQSAbstract Queued Synchronizer 抽象同步队列位于java.util.concurrent.locks包下是JUC其他锁实现的基础AQS 是一个用来构建锁和同步器的框架使用 AQS 能简单且高效地构造出同步器 是 JUC 中 核 心 的 组 件 , 比如我 们提到的 ReentrantLock,CountDownLatch 等等都是基于 AQS 来实现。 只要搞懂了 AQS那么 JUC类中的绝大部分api都可以搞定AQS思路 在类中维护一个state变量然后维护一个队列以及获取锁释放锁的方法 当线程创建后先判断state值为0没有线程使用把state1执行完成后将state0期间如果有其他的线程访问state若等于1将其他线程放入类中的队列中。(公平的实现)AQS 的锁模式分为独占和共享独占锁每次只能有一个线程持有锁比如 ReentrantLock 就是以独占方式实现的互斥锁。 共 享 锁 允 许 多 个 线 程 同 时 获 取 锁 并 发 访 问 共 享 资 源 比 如ReentrantReadWriteLockReentrantLock锁无参构造默认是非公平实现参数为true- 公平实现false-非公平实现ReentrantLock 类内部总共存在 Sync、NonfairSync、FairSync 三个类 NonfairSync 与FairSync 类 继 承 自Sync 类 Sync 类 继 承自 AbstractQueuedSynchronizer 抽象类。abstractstaticclassSyncextendsAbstractQueuedSynchronizer非公平实现源码
staticfinalclassNonfairSyncextendsSync {
//加锁
finalvoidlock() {
//若通过 CAS 设置变量 state 成功就是获取锁成功则将当前线程设置为独占线程。
//若通过 CAS 设置变量 state 失败就是获取锁失败则进入 acquire 方法进行后续处理。if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);
}//尝试获取锁无论是否获得都立即返回protectedfinalbooleantryAcquire(intacquires) {returnnonfairTryAcquire(acquires);}
}公平实现源码staticfinalclassFairSyncextendsSync { finalvoidlock() { // 以独占模式获取对象忽略中断 acquire(1);//底层实现交由 AbstractQueuedSynchronizer } }JUC包中的常用类这些都是线程安全的实现类底层都是基于AQS实现ConcurrentHashMapHashtable线程安全的但直接锁住的是整个方法效率低ConcurrentHashMap是线程安全的实现类效率是高于Hashtable的hashMap和ConcurrentHashMap都不能存储键值为null的元素,比如get方法返回的是一个null我们无法确定集合中不存在这个键还是这个键对应的值是null就是模糊不清的。CopyOnWriteArrayList将读取的操作发挥到机制读读、读写都不是互斥的且读的时候不加锁写的时候加锁。提高读的效率实现原理是在进行addset等修改操作时先将数组进行备份对备份的数组进行修改完成后将修改后的数组赋值给原数组提高了读的效率CopyOnWriteArraySet注去重方式与Set集合是不一样的不能存储重复数据是线程安全的CountDownLatch辅助类可以实现让一个线程暂停等待其他线程各自执行完毕后再自动执行。底层实现也是通过AQS实现的创建一个CountDownLatch对象后时构造方法中传入一个值就是state的值每当一个线程执行完毕state就-1直到所有线程都执行完state等于0时暂停的线程就可以回复工作了。