锁用于解决多线程对共享资源的同时访问,而引起的非线程安全问题:某一时该只有一条线程可以访问共享资源,达到了线程安全的目的,但同时也限制了并发处理的速度。
锁的分类:
同步锁: synchronized 是java 内置的语法
可重入锁:ReentrantLock 是一个java类
读写锁:ReentrantReadWriteLock 是一个java类
锁定的范围:
由于锁使线程互斥访问,未获得锁的线程会阻塞,限制了并发处理的速度,因此线程应该锁定尽量小的范围及尽快的释放锁。
比如一家企业,有10个厕所,每个厕所有5个坑,每个员工都要上厕所,厕所的同一个坑不可能由多人共同使用,每个员工相当于一线线程,茅坑相当于共享资源,因此需要多个员工之间互斥使用同一个茅坑。
错误的锁定范围:
10个厕所:意味着 某个员工使用某个茅坑时,所有厕所都不能使用,严重浪费资源,影响并发使用率。
每个厕所:意味着 某个员工使用某个茅坑时,该厕所不能被别人使用,其他9个厕所允许9个人分别使用,浪费资源,影响并发使用率。
正确的锁定范围:
每个茅坑:意味着 某个员工使用某个茅坑时,该茅坑不能被别人使用,其他49个茅坑允许49个人分别使用。
java中的锁定对象:
synchronized的锁定对象:
语法:synchronized(被锁定对象) 或 在方法签名上声明
全局锁定:Class对象,static 对象及方法,singleton 实例,equals相等的String对象
部分锁定:某个多例类的实例,不同实例由不同的线程同时访问。
public class Test { public synchronized void kk(){//做用于方法,锁定当前实例,不同实例间不影响 } public static synchronized void ww(){//做用于静态方法锁定的是Class对象 } public void t(Object obj){ synchronized(obj){//锁定指定对象 // } } public void f( ){ synchronized(this){//锁定当前实例 // } } }
ReentrantLock 锁定对象:
同一个ReentrantLock实例,不同实例可由不同线程同时访问。
用法:
class X { private final ReentrantLock lock = new ReentrantLock(); public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }
ReentrantReadWriteLock
readLock 共享锁,占用锁时,同一个ReentrantReadWriteLock实例的writeLock,被阻塞,同一个ReentrantReadWriteLock实例的readLock可以同时访问。
writeLock 独占锁,占用锁时,同一个ReentrantReadWriteLock实例的writeLock和readLock阻塞,直至锁被释放,不同实例可由不同线程同时访问
锁的释放:
1 代码执行完成,退出锁定
2.由于条件不足,而无法继续执行,主动释锁定,等待条件满足,当条件满足时,需要另一条线程唤醒等待线程,唤醒的线程争得锁之后主动释放锁的代码之后执行
A.synchronized
1.synchronized方法或代码块执行完成,而释放锁
2.synchronized:被锁定对象.wait()方法被调用时释放锁而等待, 被唤醒方式:被锁定对象.notifyAll()(这两个方法需要执行锁时才能执行)
B. ReentrantLock
1.代码执行完成后,ReentrantLock.unlock()代码被调用,而释放锁
2.由ReentrantLock.newCondition()生成Condition对象的await()方法被调用时,释放锁而等待,被唤醒方式同一个Condition对象的signalAll方法被调用。(这两个方法需要执行锁时才能执行)
C.ReentrantReadWriteLock
1.代码执行完成后,ReentrantReadWriteLock的readLock 或writeLock 对象的unlock方法被调用,而释放锁
2.readLock 不支持由条件不足释放锁定而等待条件满足。writeLock.newCondition()生成Condition对象的await()方法被调用时,释放锁而等待,被唤醒方式同一个Condition对象的signalAll方法被调用。(这两个方法需要执行锁时才能执行)
class RWDictionary { private final Map<String, Data> m = new TreeMap<String, Data>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); public Data get(String key) { r.lock(); try { return m.get(key); } finally { r.unlock(); } } public String[] allKeys() { r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); } } public Data put(String key, Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock(); } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); } }
信号量Semaphore :
一般用于限制对某些资源固定数量的访问。
Semaphore维护了N个的许可,某线程通过acquire()获取一个许可或acquire(int permits) 获取多许可,如果许可数量N大于线程要求的许可数,线程得到许可并可以继续执行。
否则线程阻塞,等待某线程释放许可。
某线程释放许可,许可数量增加并唤醒被阻塞的线程,阻塞线程唤醒后再试着获取许可,获取成功则继续执行否则再次阻塞。
不使用锁解决非线程安全问题(有一定局限性):
实现方式:一般使用CAS (compare and swap) 实现
使用场景:AtomicLongFieldUpdater 对volatile long 字段进行原子更新
AtomicReferenceFieldUpdater 对 volatile 字段进行原子更新
AtomicReference 原子方式更新的对象引用
示例:ConcurrentLinkedQueue
boolean casNext(Node<E> cmp, Node<E> val) { return nextUpdater.compareAndSet(this, cmp, val); } public boolean offer(E e) { if (e == null) throw new NullPointerException(); Node<E> n = new Node<E>(e, null); for (;;) { Node<E> t = tail; Node<E> s = t.getNext(); if (t == tail) { if (s == null) { if (t.casNext(s, n)) { casTail(t, n); return true; } } else { casTail(t, s); } } } } private static final AtomicReferenceFieldUpdater<Node, Node> nextUpdater = AtomicReferenceFieldUpdater.newUpdater (Node.class, Node.class, "next");
相关推荐
"Hasp加密锁使用手册" Hasp加密锁是一种广泛应用于软件保护和加密的技术,通过使用Hasp加密锁,可以对软件进行加密保护,防止反编译和非法使用。本手册将详细介绍Hasp加密锁的使用方法和原理。 一、Hasp加密锁类型...
《电子密码锁使用说明》 电子密码锁是一种现代化的安全设备,广泛应用于家庭、办公室和商业场所,以提供方便且安全的门禁管理。本使用说明将详细介绍电子密码锁的各个部分,安装步骤,操作方法以及相关性能指标。 ...
**Redis 分布式锁使用详解** 在分布式系统中,数据一致性是至关重要的,而实现这一目标的一个关键组件就是分布式锁。Redis,作为一个高性能的键值存储系统,由于其丰富的数据结构和优秀的性能,常被用来实现分布式...
"java常用锁使用demo工程"是一个实践项目,旨在帮助开发者理解并熟练掌握Java中的锁机制。在这个工程中,我们可能会看到各种锁的实例,如内置锁(synchronized)、显式锁(java.util.concurrent.locks包中的Lock接口...
通过学习和实践这个“redis分布式锁使用实例”,你可以深入理解如何在实际项目中使用 Redis 和 Redisson 来实现高效且可靠的分布式锁,这对于处理分布式系统中的并发控制至关重要。同时,这也为你提供了设计和实现...
Dahua大华V7系列智能锁使用说明书.pdf
4. 行级排它锁(RX锁):行级排它锁通常在`INSERT`、`UPDATE`或`DELETE`语句执行时使用,它比行级锁限制更多,因为它阻止其他事务加排它锁。其他事务可以进行查询、插入、更新和删除操作,但不能加排它锁。 Oracle...
智能锁使用教程
物流公司在途系统电子锁使用管理规定.pdf
多线程编程:互斥锁使用。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可执行...
由于这个CA锁可能与湖北省发放的其他锁驱动存在冲突,因此建议不要在同台电脑上同时使用。下面是详细的使用步骤: 1. **下载CA驱动**: 进入荆门公共资源交易网的“网上交易—网员管理—企业信息库—附件下载”...
- **如果事先对锁信息一无所知**,可以使用`onstat -k | grep X`命令来获取锁的相关信息。例如,执行`onstat -k`命令后,我们可以看到以下锁的信息输出: ``` Locks address wtlist owner lklist type tblsnum ...
中国结智能锁CK8080A玻璃门专用指纹锁说明书
以下是一个简单的互斥锁使用例子: ```cpp #include // 全局互斥锁 HANDLE g_hMutex = NULL; void ThreadFunction() { // 获取互斥锁,如果已被其他线程持有,则阻塞当前线程 if (WaitForSingleObject(g_...
《亚太天能指纹锁产品通用说明书》详细解读 亚太天能作为智能锁领域的知名品牌,其指纹锁产品以其安全性和便捷性赢得了市场的广泛认可。本文将深入解析该产品的使用手册,帮助用户更好地理解和操作这款高科技安全...
1.常见的磁力锁安装方法:简易安装、ZL支架安装、UL支架安装 2.常见的磁力锁接线方法,带反馈信号等 3.文档为说明书纸质扫描件