(多线程与并发)面试题03--java中读写锁ReadWriteLock
来源:互联网 发布:中国经济数据造假 编辑:程序博客网 时间:2024/04/27 18:52
1.排他锁(互斥锁)的概念:
synchronized,ReentrantLock这些锁都是排他锁,这些锁同一时刻只允许一个线程进行访问。
2.读写锁的概念:
分为读锁和写锁,多个读锁不互斥,读锁和写锁互斥,写锁与写锁互斥。
3.读写锁的好处:
为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。
原来使用的互斥锁只能同时间有一个线程在运行,现在的读写锁同一时刻可以多个读锁同时运行,这样的效率比原来的排他锁(互斥锁)效率高。
4.读写锁的原理分析:
Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock,
lock方法 是基于CAS 来实现的
源码:
public interface ReadWriteLock { /** * Returns the lock used for reading. * * @return the lock used for reading. */ Lock readLock(); /** * Returns the lock used for writing. * * @return the lock used for writing. */ Lock writeLock();}
5.案例一:
package WriteReadLock;import java.util.Random;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriterLockTest {public static void main(String[] args) {final Queue q3 = new Queue();for(int i=0;i<3;i++){new Thread(){public void run(){while(true){q3.get();}}}.start();}for(int i=0;i<3;i++){new Thread(){public void run(){while(true){q3.put(new Random().nextInt(10000));}}}.start(); }}}class Queue{//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。private Object data = null;//得到读写锁ReadWriteLock readWriteLock = new ReentrantReadWriteLock();/** * 将用于读的get()和写的put()放在同一个类中这样是为了对同一个资源data进行操作,形成互斥 *//** * 进行读操作 * 可以多个读线程同时进入,写线程不能执行 */public void get(){//获取读锁,并加锁Lock readLock = readWriteLock.readLock();readLock.lock();try {System.out.println(Thread.currentThread().getName() + " be ready to read data!");Thread.sleep((long)(Math.random()*1000));System.out.println(Thread.currentThread().getName() + "have read data :"+ data);} catch (InterruptedException e) {e.printStackTrace();}finally {//!!!!!!注意:锁的释放一定要在trycatch的finally中,因为如果前面程序出现异常,锁就不能释放了//释放读锁readLock.unlock();}}/** * 进行写操作 * 只能一个写线程进入,读线程不能执行 */public void put(Object data){//获取写锁,并加锁Lock writeLock = readWriteLock.writeLock();writeLock.lock();try {System.out.println(Thread.currentThread().getName() + " be ready to write data!");Thread.sleep((long)(Math.random()*1000));this.data = data;System.out.println(Thread.currentThread().getName() + " have write data: " + data);} catch (InterruptedException e) {e.printStackTrace();}finally {//释放写锁writeLock.unlock();}}}
在加入读写锁之后:读的过程中,不会有写
6.案例二:
package WriteReadLock;import java.util.HashMap;import java.util.Map;import java.util.Random;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class CacheDemo {//用map来模拟缓存Map<String,Object> cache = new HashMap<String,Object>();ReadWriteLock readWriteLock = new ReentrantReadWriteLock();public static void main(String[] args) {final CacheDemo cacheDemo = new CacheDemo();for(int i=0;i<6;i++){new Thread(){public void run(){while(true){System.out.println(cacheDemo.getData("key1").toString());}}}.start();}}Lock readLock = readWriteLock.readLock();Lock writeLock = readWriteLock.writeLock();//这里必须要用volatie当一个写线程设置value="aaaabbbb",一定要让其他的线程知道vlue的变化,这样就不会被重复写volatile Object value;public Object getData(String key){readLock.lock();try {Thread.sleep(300);System.out.println(" read"); value = cache.get(key);if (value == null) {//这里已经加了读锁,读锁中写是不能允许的,所以要把这个锁释放掉readLock.unlock();writeLock.lock();//防止,当多个写者进程在等待,前面的写进程已经赋值了,value已经不为空了后面的等着的写进程仍然继续赋值if(value == null){System.out.println("find null"); value="aaaabbbb";cache.put(key, value);System.out.println("write");}writeLock.unlock();//从新加上读锁readLock.lock();}return value;} catch (Exception e) {e.printStackTrace();}finally {readLock.unlock();}return null;}}
1 0
- (多线程与并发)面试题03--java中读写锁ReadWriteLock
- Java多线程与并发库高级应用之读写锁ReadWriteLock
- 【Java多线程】-读写锁ReadWriteLock
- Java多线程中读写锁ReadWriteLock的使用
- Java多线程/并发06、线程锁Lock与ReadWriteLock
- Java中读写锁ReadWriteLock
- java中读写锁ReadWriteLock
- 转载-java多线程与并发面试题
- java面试题_并发与多线程
- java 读写锁 ReadWriteLock
- Java读写锁ReadWriteLock
- 多线程 - 显式锁-读写锁ReadWriteLock
- java多线程,并发面试题
- java并发编程系列之ReadWriteLock读写锁的使用
- Java 并发 —— 读写锁(ReadWriteLock)
- java—读写锁ReadWriteLock
- 理解java读写锁 ReadWriteLock
- 并发编程之ReadWriteLock读写锁
- 056_最长公共子序列
- Linux网络编程入门
- 23种设计模式(17)_行为型_中介者模式(Mediator Pattern)
- xcode7 Enable Zombie Objects 没反应...
- Makefile 使用总结
- (多线程与并发)面试题03--java中读写锁ReadWriteLock
- 自动化管理工具Saltstack之用户管理篇(6)
- 将字符串 数组 字典写入本地文件,并计算文件的大小,最后删除文件
- GIS的刊物
- 自适应高度
- 第一类Stirling数和第二类Stirling数
- hp rx6600报1,2,3号风扇同时故障
- tomcat配置文件server.xml详解
- 关于ubuntu12.04下google-chrome无法启动问题的解决