线程同步Lock锁
Lock接口历史
java1.5版本之前只有synchronized一种锁,lock是java1.5版本之后提供的接口。lock接口与synchronized接口功能相同,但是需要手动获取锁和释放锁。既然提供了lock锁那必然就有一定的优点,例如:
lock锁具有锁的可操作性,可以中断获取和超时获取锁等多种同步获取锁的优点。除此之外,lock锁还有一个非常强大的实现类重入锁和读写锁。
Lock接口的使用
Lock lock = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
lock.ublock();
}
lock接口和synchronized关键字的接口的区别
lock可以尝试非阻塞的获取锁,如果这一时刻没有被其他线程获取到,则成功获取。
Lock接口能被中断的获取锁,获取到锁的线程能够相应中断,当获取到锁的线程被中断时,中断异常将被抛出,并释放锁。
Lock接口可以在指定时间内获取锁,如果在有效时间内未获取到锁则返回。
Lock接口中长用的方法
void lock() //获取锁
void unlock() //释放锁
boolean trylock() //尝试获取锁,如果获取失败返回false
boolean trylcok(long time,TimeUtil util) //在指定时间内获取锁,若获取失败则返回false
void lockInterruptibly() //如果当前线程未被中断则获取锁。该方法也是获取锁,与lock()不同的是,该方法在获取过程中可以被中断
Lock中的重入锁ReetrantLock实现类
顾名思义,重入锁就是在一条线程获取到锁之后再次获取锁,就是所谓的重入锁。讲道理synchronized也同样可以做到,不同的是该实现类有个很重到的特性,就是可以实现公平与非公平获取。
公平获取就是线程等待时间越长的越先获取到锁,反之就是非公平获取。事实上,非公平获取要比公平获取的效率要高。
当然该锁是排他锁,也就是说在一个线程获取锁后,其他线程进入等待列队。即同一时刻有且只能有一个线程执行。
Lock锁中的读写锁ReetrantReadWriteLock
与重入锁有所不同的是,读写锁在同一时刻可以有多个线程同时访问。但在写线程访问时,其他读锁和写锁都将被阻塞,进入等待列队。读写锁维护了一对儿锁,一个读锁和一个写锁。通过读写锁分离,使得程序执行效率比一般的排他锁更高。(并发性:在资料上看到的是并发性更高,在这里我觉得效率更容易理解一丢丢)
读锁:readlock();
写锁:writelock();
public class Cache{
static Map<String,Object> map = new HashMap<String,Object>();
static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
static Lock rLock = rwl.readLock();
static Lock wLock = rwl.writeLock();
//获取一个key对应的value
public static final Object get(String key){
r.lock();
try{
return map.get(key);
}finally{
r.unlock();
}
}
//设置key对应的value并返回旧的value
public static fianl Object put(String key,Object value){
w.lock();
try{
return map.put(key,value);
}final{
w.unlock();
}
}
//清空缓存
public static fianl void clear(){
w.lock();
try{
map.clear();
} finally{
w.unlock();
}
}
}
读写锁的锁降级
锁降级是指写锁降级成为读锁。如果当前线程持有写锁,然后将其释放再获取读锁的过程不能称为锁降级。锁降级指的在持有写锁的时候再获取读锁,获取到读锁后释放之前写锁的过程称为锁释放。
锁降级在某些情况下是非常必要的,主要是为了保证数据的可见性。如果当前线程不获取读锁而直接释放写锁,假设此时另外一个线程获取了写锁并修改了数据。那么当前线程无法感知该线程的数据更新。
(没怎么看明白,用程序走几次就明白了。实践见真理)。
线程同步Lock锁的更多相关文章
- 线程同步——lock锁
线程同步即解决线程安全问题的第三种方式——使用lock锁 代码实现: 其中,ReentrantLock是lock接口的实现类,这边是使用多态创建,访问成员方法时,编译看左,运行看右: Reentran ...
- C#关于多线程及线程同步 lock锁的应用
Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.D ...
- python笔记10-多线程之线程同步(锁lock)
前言 关于吃火锅的场景,小伙伴并不陌生,吃火锅的时候a同学往锅里下鱼丸,b同学同时去吃掉鱼丸,有可能会导致吃到生的鱼丸. 为了避免这种情况,在下鱼丸的过程中,先锁定操作,让吃火锅的小伙伴停一会,等鱼丸 ...
- 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock
[源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...
- Java提高班(三)并发中的线程同步与锁
乐观锁.悲观锁.公平锁.自旋锁.偏向锁.轻量级锁.重量级锁.锁膨胀...难理解?不存的!来,话不多说,带你飙车. 上一篇介绍了线程池的使用,在享受线程池带给我们的性能优势之外,似乎也带来了另一个问题: ...
- Java并发包——线程同步和锁
Java并发包——线程同步和锁 摘要:本文主要学习了Java并发包里有关线程同步的类和锁的一些相关概念. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520 ...
- 线程同步 Lock接口
同步:★★★★★ 好处:解决了线程安全问题. 弊端:相对降低性能,因为判断锁需要消耗资源,产生了死锁. 定义同步是有前提的: 1,必须要有两个或者两个以上的线程,才需要同步. 2,多个线程必须保证使用 ...
- c# 线程同步各类锁
1)原子操作(Interlocked):所有方法都是执行一次原子读取或一次写入操作. 2)lock()语句:避免锁定public类型,否则实例将超出代码控制的范围,定义private对象来锁定. 3) ...
- 【转】多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上)
本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过 本篇的介绍能对常见的线程同步方法有一个整体的认识,而对 ...
随机推荐
- IDEA抽取方法的快捷键
正常的话是 ctrl+alt+m 如果快捷键占用或者修改过,在写代码的地方右键->refactor->extract->method
- [ZJCTF 2019]NiZhuanSiWei
0x00知识点 1:data伪协议写入文件 2:php:// php://filter用于读取源码 php://input用于执行php代码 3反序列化 0x01解题 打开题目,给了我们源码 < ...
- vzray上网教程
1.首先按照之前的教程在chrome里安装插件-Proxy-SwitchyOmega-Chromium-2.5.15 2.打开 vzray-v3.11-windows-64,打开 3.在chrome ...
- 装饰器参数加log
#有多个函数,需要计算他们的执行时间,加logimport timedef logger(flag): def show_time(f): #foo对象 def inner(*x,**y): star ...
- cisco路由器license的相关命令简单梳理(转)
转自https://blog.51cto.com/legendland/1900185作者:legendlandlicense:对于IP Base基本的IOS功能外,另外三个技术包(1 数据Data: ...
- macos上命令行查看磁盘序列号
收集到两种命令行获取方法:(另外https://www.maketecheasier.com/find-mac-serial-number/中还说明了GUI模式下的查看方法) 1.system_pro ...
- python学习Day08--文件操作
[主要内容] 文件操作: 1. r 2. w 3. a 4. r+ 读写模式. 需要移动光标进行反复读写 5. w+ 6. a+ 7. b bytes 读写操作的是字节. 用在非文本上 8. seek ...
- 吴裕雄--天生自然TensorFlow高层封装:解决ImportError: cannot import name 'tf_utils'
将原来版本的keras卸载了,再安装2.1.5版本的keras就可以了.
- Servlet&JSP复习笔记 01
1. Servlet 含义:服务器端的小程序,它只是服务器中的一部分. Servlet Little 标准:Sun公司制定的一种用来扩展Web服务器功能的组件规范. a. 扩展web服务器功能:扩展w ...
- spring02-组件注册-@ComponentScan-自动扫描组件&指定扫描规则
上一篇我们讲到,讲@Bean注解标在某个方法上,那么ioc容器启动的时候就会将方法返回值放到ioc容器中 在开发中,实际上包扫描用的比较多,接下来我们会介绍两种方式一种是基于xml,一种是基于注解. ...