当前位置: 首页 > news >正文

重庆建设机电网站恋家网邯郸房产

重庆建设机电网站,恋家网邯郸房产,北京通网站建设价格低,西安知名网站制作公司目录 4.1.9. JAVA 锁 4.1.9.1. 乐观锁 4.1.9.2. 悲观锁 4.1.9.3. 自旋锁 4.1.9.4. Synchronized 同步锁 Synchronized 作用范围 Synchronized 核心组件 Synchronized 实现 4.1.9.5. ReentrantLock Lock 接口的主要方法 非公平锁 公平锁 ReentrantLock 与 synchronized …                                 目录 4.1.9. JAVA 锁 4.1.9.1. 乐观锁 4.1.9.2. 悲观锁 4.1.9.3. 自旋锁 4.1.9.4. Synchronized 同步锁 Synchronized 作用范围 Synchronized 核心组件 Synchronized 实现 4.1.9.5. ReentrantLock Lock 接口的主要方法 非公平锁 公平锁         ReentrantLock 与 synchronized ReentrantLock 实现 Condition 类和 Object 类锁方法区别区别 tryLock 和 lock 和 lockInterruptibly 的区别 4.1.9. JAVA 锁 4.1.9.1. 乐观锁 乐观锁是一种乐观思想即认为读多写少遇到并发写的可能性低每次去拿数据的时候都认为 别人不会修改所以不会上锁但是在更新的时候会判断一下在此期间别人有没有去更新这个数 据采取在写时先读出当前版本号然后加锁操作比较跟上一次的版本号如果一样则更新 如果失败则要重复读-比较-写的操作。 java 中的乐观锁基本都是通过 CAS 操作实现的CAS 是一种更新的原子操作比较当前值跟传入 值是否一样一样则更新否则失败。 4.1.9.2. 悲观锁 悲观锁是就是悲观思想即认为写多遇到并发写的可能性高每次去拿数据的时候都认为别人 会修改所以每次在读写数据的时候都会上锁这样别人想读写这个数据就会 block 直到拿到锁。 java中的悲观锁就是Synchronized,AQS框架下的锁则是先尝试cas乐观锁去获取锁获取不到 才会转换为悲观锁如 RetreenLock。 4.1.9.3. 自旋锁 自旋锁原理非常简单如果持有锁的线程能在很短时间内释放锁资源那么那些等待竞争锁 的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态它们只需要等一等自旋 等持有锁的线程释放锁后即可立即获取锁这样就避免用户线程和内核的切换的消耗。 线程自旋是需要消耗 cup 的说白了就是让 cup 在做无用功如果一直获取不到锁那线程 也不能一直占用 cup 自旋做无用功所以需要设定一个自旋等待的最大时间。 如果持有锁的线程执行的时间超过自旋等待的最大时间扔没有释放锁就会导致其它争用锁 的线程在最大等待时间内还是获取不到锁这时争用线程会停止自旋进入阻塞状态。 自旋锁的优缺点 自旋锁尽可能的减少线程的阻塞这对于锁的竞争不激烈且占用锁时间非常短的代码块来 说性能能大幅度的提升因为自旋的消耗会小于线程阻塞挂起再唤醒的操作的消耗这些操作会 导致线程发生两次上下文切换 但是如果锁的竞争激烈或者持有锁的线程需要长时间占用锁执行同步块这时候就不适合 使用自旋锁了因为自旋锁在获取锁前一直都是占用 cpu 做无用功占着 XX 不 XX同时有大量 线程在竞争一个锁会导致获取锁的时间很长线程自旋的消耗大于线程阻塞挂起操作的消耗 其它需要 cup 的线程又不能获取到 cpu造成 cpu 的浪费。所以这种情况下我们要关闭自旋锁 自旋锁时间阈值1.6 引入了适应性自旋锁 自旋锁的目的是为了占着 CPU 的资源不释放等到获取到锁立即进行处理。但是如何去选择 自旋的执行时间呢如果自旋执行时间太长会有大量的线程处于自旋状态占用 CPU 资源进而 会影响整体系统的性能。因此自旋的周期选的额外重要、 JVM 对于自旋周期的选择jdk1.5 这个限度是一定的写死的在 1.6 引入了适应性自旋锁适应 性自旋锁意味着自旋的时间不在是固定的了而是由前一次在同一个锁上的自旋时间以及锁的拥 有者的状态来决定基本认为一个线程上下文切换的时间是最佳的一个时间同时 JVM 还针对当 前 CPU 的负荷情况做了较多的优化如果平均负载小于 CPUs 则一直自旋如果有超过(CPUs/2) 个线程正在自旋则后来线程直接阻塞如果正在自旋的线程发现 Owner 发生了变化则延迟自旋 时间自旋计数或进入阻塞如果 CPU 处于节电模式则停止自旋自旋时间的最坏情况是 CPU 的存储延迟CPU A 存储了一个数据到 CPU B 得知这个数据直接的时间差自旋时会适当放 弃线程优先级之间的差异。 自旋锁的开启 JDK1.6 中-XX:UseSpinning 开启 -XX:PreBlockSpin10 为自旋次数 JDK1.7 后去掉此参数由 jvm 控制 4.1.9.4. Synchronized 同步锁 synchronized 它可以把任意一个非 NULL 的对象当作锁。他属于独占式的悲观锁同时属于可重 入锁。 Synchronized 作用范围 1. 作用于方法时锁住的是对象的实例(this) 2. 当作用于静态方法时锁住的是Class实例又因为Class的相关数据存储在永久带PermGen jdk1.8 则是 metaspace永久带是全局共享的因此静态方法锁相当于类的一个全局锁 会锁所有调用该方法的线程 3. synchronized 作用于一个对象实例时锁住的是所有以该对象为锁的代码块。它有多个队列 当多个线程一起访问某个对象监视器的时候对象监视器会将这些线程存储在不同的容器中。 Synchronized 核心组件 1) Wait Set哪些调用 wait 方法被阻塞的线程被放置在这里 2) Contention List竞争队列所有请求锁的线程首先被放在这个竞争队列中 3) Entry ListContention List 中那些有资格成为候选资源的线程被移动到 Entry List 中 4) OnDeck任意时刻最多只有一个线程正在竞争锁资源该线程被成为 OnDeck 5) Owner当前已经获取到所资源的线程被称为 Owner 6) !Owner当前释放锁的线程。 Synchronized 实现 1. JVM 每次从队列的尾部取出一个数据用于锁竞争候选者OnDeck但是并发情况下 ContentionList 会被大量的并发线程进行 CAS 访问为了降低对尾部元素的竞争JVM 会将 一部分线程移动到 EntryList 中作为候选竞争线程。 2. Owner 线程会在 unlock 时将 ContentionList 中的部分线程迁移到 EntryList 中并指定 EntryList 中的某个线程为 OnDeck 线程一般是最先进去的那个线程。 3. Owner 线程并不直接把锁传递给 OnDeck 线程而是把锁竞争的权利交给 OnDeck OnDeck 需要重新竞争锁。这样虽然牺牲了一些公平性但是能极大的提升系统的吞吐量在 JVM 中也把这种选择行为称之为“竞争切换”。 4. OnDeck 线程获取到锁资源后会变为 Owner 线程而没有得到锁资源的仍然停留在 EntryList 中。如果 Owner 线程被 wait 方法阻塞则转移到 WaitSet 队列中直到某个时刻通过 notify 或者 notifyAll 唤醒会重新进去 EntryList 中。 5. 处于 ContentionList、EntryList、WaitSet 中的线程都处于阻塞状态该阻塞是由操作系统 来完成的Linux 内核下采用 pthread_mutex_lock 内核函数实现的。 6. Synchronized 是非公平锁。 Synchronized 在线程进入 ContentionList 时等待的线程会先 尝试自旋获取锁如果获取不到就进入 ContentionList这明显对于已经进入队列的线程是 不公平的还有一个不公平的事情就是自旋获取锁的线程还可能直接抢占 OnDeck 线程的锁 资源。 参考https://blog.csdn.net/zqz_zqz/article/details/70233767 7. 每个对象都有个 monitor 对象加锁就是在竞争 monitor 对象代码块加锁是在前后分别加 上 monitorenter 和 monitorexit 指令来实现的方法加锁是通过一个标记位来判断的 8. synchronized 是一个重量级操作需要调用操作系统相关接口性能是低效的有可能给线 程加锁消耗的时间比有用操作消耗的时间更多。 9. Java1.6synchronized 进行了很多的优化有适应自旋、锁消除、锁粗化、轻量级锁及偏向 锁等效率有了本质上的提高。在之后推出的 Java1.7 与 1.8 中均对该关键字的实现机理做 了优化。引入了偏向锁和轻量级锁。都是在对象头中有标记位不需要经过操作系统加锁。 10. 锁可以从偏向锁升级到轻量级锁再升级到重量级锁。这种升级过程叫做锁膨胀 11. JDK 1.6 中默认是开启偏向锁和轻量级锁可以通过-XX:-UseBiasedLocking 来禁用偏向锁。 4.1.9.5. ReentrantLock ReentantLock 继承接口 Lock 并实现了接口中定义的方法他是一种可重入锁除了能完 成 synchronized 所能完成的所有工作外还提供了诸如可响应中断锁、可轮询锁请求、定时锁等 避免多线程死锁的方法。 Lock 接口的主要方法 1. void lock(): 执行此方法时, 如果锁处于空闲状态, 当前线程将获取到锁. 相反, 如果锁已经 被其他线程持有, 将禁用当前线程, 直到当前线程获取到锁. 2. boolean tryLock()如果锁可用, 则获取锁, 并立即返回 true, 否则返回 false. 该方法和 lock()的区别在于, tryLock()只是试图获取锁, 如果锁不可用, 不会导致当前线程被禁用, 当前线程仍然继续往下执行代码. 而 lock()方法则是一定要获取到锁, 如果锁不可用, 就一 直等待, 在未获得锁之前,当前线程并不继续向下执行. 3. void unlock()执行此方法时, 当前线程将释放持有的锁. 锁只能由持有者释放, 如果线程 并不持有锁, 却执行该方法, 可能导致异常的发生. 4. Condition newCondition()条件对象获取等待通知组件。该组件和当前的锁绑定 当前线程只有获取了锁才能调用该组件的 await()方法而调用后当前线程将缩放锁。 5. getHoldCount() 查询当前线程保持此锁的次数也就是执行此线程执行 lock 方法的次 数。 6. getQueueLength返回正等待获取此锁的线程估计数比如启动 10 个线程1 个 线程获得锁此时返回的是 9 7. getWaitQueueLengthCondition condition返回等待与此锁相关的给定条件的线 程估计数。比如 10 个线程用同一个 condition 对象并且此时这 10 个线程都执行了 condition 对象的 await 方法那么此时执行此方法返回 10 8. hasWaiters(Condition condition)查询是否有线程等待与此锁有关的给定条件 (condition)对于指定 contidion 对象有多少线程执行了 condition.await 方法 9. hasQueuedThread(Thread thread)查询给定线程是否等待获取此锁 10. hasQueuedThreads()是否有线程等待此锁 11. isFair()该锁是否公平锁 12. isHeldByCurrentThread() 当前线程是否保持锁锁定线程的执行 lock 方法的前后分 别是 false 和 true 13. isLock()此锁是否有任意线程占用 14. lockInterruptibly如果当前线程未被中断获取锁 15. tryLock尝试获得锁仅在调用时锁未被线程占用获得锁 16. tryLock(long timeout TimeUnit unit)如果锁在给定等待时间内没有被另一个线程保持 则获取该锁。 非公平锁 JVM 按随机、就近原则分配锁的机制则称为不公平锁ReentrantLock 在构造函数中提供了 是否公平锁的初始化方式默认为非公平锁。非公平锁实际执行的效率要远远超出公平锁除非 程序有特殊需要否则最常用非公平锁的分配机制。 公平锁         公平锁指的是锁的分配机制是公平的通常先对锁提出获取请求的线程会先被分配到锁 ReentrantLock 在构造函数中提供了是否公平锁的初始化方式来定义公平锁。 ReentrantLock 与 synchronized 1. ReentrantLock 通过方法 lock()与 unlock()来进行加锁与解锁操作与 synchronized 会 被 JVM 自动解锁机制不同ReentrantLock 加锁后需要手动进行解锁。为了避免程序出 现异常而无法正常解锁的情况使用 ReentrantLock 必须在 finally 控制块中进行解锁操 作。 2. ReentrantLock 相比 synchronized 的优势是可中断、公平锁、多个锁。这种情况下需要 使用 ReentrantLock。 ReentrantLock 实现 public class MyService {private Lock lock new ReentrantLock();//Lock locknew ReentrantLock(true);//公平锁//Lock locknew ReentrantLock(false);//非公平锁private Condition conditionlock.newCondition();//创建 Conditionpublic void testMethod() {try {lock.lock();//lock 加锁//1wait 方法等待//System.out.println(开始 wait);condition.await();//通过创建 Condition 对象来使线程 wait必须先执行 lock.lock 方法获得锁//:2signal 方法唤醒condition.signal();//condition 对象的 signal 方法可以唤醒 wait 线程for (int i 0; i 5; i) { System.out.println(ThreadName Thread.currentThread().getName() ( (i 1)));}} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();}} }Condition 类和 Object 类锁方法区别区别 1. Condition 类的 awiat 方法和 Object 类的 wait 方法等效 2. Condition 类的 signal 方法和 Object 类的 notify 方法等效 3. Condition 类的 signalAll 方法和 Object 类的 notifyAll 方法等效 4. ReentrantLock 类可以唤醒指定条件的线程而 object 的唤醒是随机的 tryLock 和 lock 和 lockInterruptibly 的区别 1. tryLock 能获得锁就返回 true不能就立即返回 falsetryLock(long timeout,TimeUnit unit)可以增加时间限制如果超过该时间段还没获得锁返回 false 2. lock 能获得锁就返回 true不能的话一直等待获得锁 3. lock 和 lockInterruptibly如果两个线程分别执行这两个方法但此时中断这两个线程 lock 不会抛出异常而 lockInterruptibly 会抛出异常
http://www.zqtcl.cn/news/352131/

相关文章:

  • asp.net做的网站模板下载万网x3 wordpress
  • 设计网站设计目标天津市建设工程管理总队网站
  • 网站开始怎么做上海响应式网页建设
  • 网站备案 seo免费二维码制作网站
  • 删除网站备案网站建设湖南岚鸿建设
  • 做vlogger的网站有哪些长沙网站排名技巧
  • 媒体营销平台商品seo关键词优化
  • 芜湖先锋网站两学一做wordpress菜单顶部
  • 网站策划怎么样一级域名网站如何申请
  • 烟台高端网站开发网站开发哪个公司好
  • 广州网站定制开发方案南宁网站 制作
  • php做网站需要后台吗郑州建网站十大
  • 网站跳出率是什么意思百度服务
  • 建站 discuz开发者导航
  • 有哪些网站可以做毕业设计外贸网站发外链
  • 如何使用网站模板计算机培训班有用吗
  • 本地宁波网站建设电子商务网站建设工具都有那些
  • 网站建设的基本目标免费 wordpress企业主题
  • 专业网站建设微信商城开发规划馆网站建设
  • 网站建设公司沈阳西安建设工程信息交易中心官网
  • 青海住房和城乡建设部网站wordpress php7.3
  • 网站后台重置密码怎么做360网站怎么做网址链接
  • 广告网站建设及推广网站建设怎样推广
  • 做网站使网页不居中滁州注册公司流程和费用
  • 做网站广告经营者个性定制网站
  • 网站开发 北京外包公司软件公司网站建设
  • 网络认证入口seo免费诊断
  • 十大知名博客网站郑州企业建站公司定制
  • 视频网站如何做引流网站首页 关键词
  • 建设机械网站精英大港做网站