博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java基础——Locks锁机制
阅读量:4291 次
发布时间:2019-05-27

本文共 2566 字,大约阅读时间需要 8 分钟。

java.util.concurrent.locks 包中,为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。

接口 Lock

public interface
Lock
Lock 实现提供了比使用
synchronized 方法和语句可获得的更广泛的锁定操作。

锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如 的读取锁。 

虽然 synchronized 方法和语句的范围机制使得使用监视器锁编程方便了很多,但有时也需要以更为灵活的方式使用锁。

随着灵活性的增加,也带来了更多的责任。不使用块结构锁就失去了使用 synchronized 方法和语句时会出现的锁自动释放功能。在大多数情况下,应该使用以下语句:

Lock l = ...;      l.lock();     try {         // access the resource protected by this lock     } finally {         l.unlock();     }

必须谨慎地确保保持锁定时所执行的所有代码用 try-finally 或 try-catch 加以保护,以确保在必要时释放锁。

所有 Lock 实现都必须 实施与内置监视器锁提供的相同内存同步语义,

ReentrantLock

一个可重入的互斥锁 ,它具有与使用
synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。
class X {   private final ReentrantLock lock = new ReentrantLock();   // ...   public void m() {      lock.lock();  // block until condition holds     try {       // ... method body     } finally {       lock.unlock()     }   } }
除了实现 接口,此类还定义了
isLocked
getLockQueueLength 方法,以及一些相关的
protected 访问方法,这些方法对检测和监视可能很有用。

此锁最多支持同一个线程发起的 2147483648 个递归锁。试图超过此限制会导致由锁方法抛出的 。 

接口 Condition

Condition
Object 监视器方法( 、 和 )分解成截然不同的对象,以便通过将这些对象与任意 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,
Lock 替代了
synchronized 方法和语句的使用,
Condition 替代了 Object 监视器方法的使用。

条件(也称为条件队列条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。 

class BoundedBuffer {   final Lock lock = new ReentrantLock();   final Condition notFull  = lock.newCondition();    final Condition notEmpty = lock.newCondition();    final Object[] items = new Object[100];   int putptr, takeptr, count;   public void put(Object x) throws InterruptedException {     lock.lock();     try {       while (count == items.length)          notFull.await();       items[putptr] = x;        if (++putptr == items.length) putptr = 0;       ++count;       notEmpty.signal();     } finally {       lock.unlock();     }   }   public Object take() throws InterruptedException {     lock.lock();     try {       while (count == 0)          notEmpty.await();       Object x = items[takeptr];        if (++takeptr == items.length) takeptr = 0;       --count;       notFull.signal();       return x;     } finally {       lock.unlock();     }   }  }
Condition 实例实质上被绑定到一个锁上。要为特定 实例获得 Condition 实例,请使用其 方法。

接口 ReadWriteLock

ReadWriteLock 维护了一对相关的 ,一个用于只读操作,另一个用于写入操作。只要没有 writer, 可以由多个 reader 线程同时保持。 是独占的。
  ()
          返回用于读取操作的锁。
  ()
          返回用于写入操作的锁。
与互斥锁相比,读-写锁允许对共享数据进行更高级别的并发访问。虽然一次只有一个线程(
writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(
reader 线程)。
你可能感兴趣的文章
很多人都没用过的轻量级Oracle数据库数据导出工具——性能超赞
查看>>
大白话讲解并发控制的悲观锁与乐观锁 / 高性能 MySQL 笔记
查看>>
javascript大量推送数据如何快速处理?
查看>>
一个关于 nolock 的故事
查看>>
关于数据库方面的面试技巧:如何从建表展现自己能力
查看>>
直击Redis持久化磁盘IO痛点,让存储不再有负担!
查看>>
CentOS 7.0 x64下Zabbix 3.0 安装笔记 / linux运维之ZABBIX通过自带web检测功能检测网站是否正常
查看>>
什么是搜索引擎分词技术?
查看>>
细说分布式Session管理
查看>>
String字符串
查看>>
java—Tomcat高性能调优方案详解
查看>>
误删mysql库不要紧,binlog数据来帮你,再也不用担心删库要跑路
查看>>
MongoDB数据库管理开源工具Robo 3T
查看>>
记一次地址服务优化(Redis使用优化)
查看>>
Oracle Database 18c 的10大新特性一览
查看>>
volatile变量与普通变量的区别
查看>>
Spring Security 使用总结
查看>>
Mysql Repliaction技术入门
查看>>
Java互联网架构-分布式系统服务治理
查看>>
阿里巴巴Java开发规约插件全球首发!
查看>>