首页 > 编程知识 正文

java读写锁实现原理,java类锁和对象锁

时间:2023-05-04 18:02:13 阅读:39396 作者:1707

两种互斥锁定机制:

1、同步

2、ReentrantLock

ReentrantLock是jdk5的新功能,通过采用ReentrantLock可以完全替换同步的传统锁定机制。 此外,ReentrantLock还可以提高面向对象和灵活性。 网上有很多文章比较两者的锁定方式,但这里很少谈论。 各位百度,谷歌这个博客也提到了这两种锁定方式实现的经典范例《生产者消费者》。

关于读写锁定,与其用语言解释,不如直接用代码解释。 以下用两个例子说明读写锁定和读写锁定的使用。

示例1 :

import java.util.HashMap;

import java.util.Map;

import Java.util.concurrent.locks.read write lock;

import Java.util.concurrent.locks.reentrantreadwritelock;

//*

* @author聪明的店员2012

*

*读写锁定:读写锁定

*

*在多线程环境中读写相同的数据时,会出现线程安全问题。 例如,当一个线程读取数据时,另一个线程

通过写入数据,导致前后数据不一致的某个线程写入数据时,也写入其他线程,同样地,成为在线程前后可见的数据的

*不一致。

*

此时,可以在读写方法中加入互斥锁。 一次只允许读取或写入一个线程,不允许其他线程的读取或写入操作。 这是

*虽然可以解决这些问题,但效率大幅下降。 因为在实际的业务场景中,用一个数据读取数据的操作次数很多

*写入数据的操作,但线程和线程之间的读取操作与线程安全无关。 如果处于读-写、写-写期间,则无需打开排他锁定

*之间锁上就行了。

*

*在这种情况下,读写锁定是最好的解决方案。

*

读/写锁定机制:

*“读-读”并不排他

*“读写”互斥

*“写-写”互斥

*

也就是说,需要随时保证。

*正在写入的线程只有一个;

*线程正在读取时,写入操作等待;

*如果线程正在写入,其他线程的写入和读取将等待。

*

*以下为缓存类: 用于指示读/写锁定的操作。 重新输入,降级

*/

公共类缓存数据{

//缓存应该都是单用户的,但在这里,我们将以单实例模式进行设计:

privatestaticcacheddatacheddata=newcacheddata (;

私密性readwritelocklock=newreentrantreadwritelock (; //读写锁定

private Map cache=new HashMap (; //缓存

私有缓存数据(

}

publicstaticcacheddatagetinstance (

返回高速数据;

}

//读缓存:

公共对象密钥{

锁定. read lock ().lock );

对象obj=null;

try {

obj=cache.get(key;

if(obj==null ) {

lock.readLock ().unlock );

//在此期间,其他线程可能会获取锁定

lock.writeLock ().lock );

try {

if(obj==null ) {

obj='查找数据库'; //实际的动作是查找数据库

//将数据更新到缓存:

cache.put(key,obj );

}

} finally {

//当前线程可以在获取写入锁定的同时获取读取锁定。 这称为锁的重载,然后导致写锁的降级,称为降级锁。

要允许重新读取到reader,请使用重新读取降级写入锁定,但当前线程维护的所有写入锁定必须已释放

//它们。 所以,在重新进入的过程中,其他线程没有机会获得锁定。 想想看。 首先解除写入锁定,在

//上读锁定,这样做有什么弊端? -这样,在解除写入锁定和获取读取锁定之前,其他线程可能会中断。

//——3354重新装入降级锁的步骤:获取写锁定,然后获取读锁定,最后

释放写入锁(重点)

lock.readLock().lock();

lock.writeLock().unlock();

}

}

} finally {

lock.readLock().unlock();

}

return obj;

}

}

例子2:

import java.util.Map;

import java.util.TreeMap;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.xml.crypto.Data;

/**

* @author 聪明的店员2012

*

* jdk文档中关于ReentrantReadWriteLock类使用的一个很好的例子,以下是具体的介绍:

*

* 在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。通常,在预期 collection

* 很大,读取者线程访问它的次数多于写入者线程,并且 entail 操作的开销高于同步开销时,这很值得一试。例如,以下

* 是一个使用 TreeMap 的类,预期它很大,并且能被同时访问。

*/

public class RWDictionary {

private final Map map = new TreeMap();

private final ReadWriteLock rwl = new ReentrantReadWriteLock();

private final Lock readLock = rwl.readLock();

private final Lock writeLock = rwl.writeLock();

public Data get(String key) {

readLock.lock();

try {

return map.get(key);

} finally {

readLock.unlock();

}

}

public String[] allKeys() {

readLock.lock();

try {

return (String[]) map.keySet().toArray();

} finally {

readLock.unlock();

}

}

public Data put(String key, Data value) {

writeLock.lock();

try {

return map.put(key, value);

} finally {

writeLock.unlock();

}

}

public void clear() {

writeLock.lock();

try {

map.clear();

} finally {

writeLock.unlock();

}

}

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。