JAVA 并发编程-读写锁之模拟缓存系统(十一)
2016-08-25 17:12
435 查看
在多线程中,为了提高效率有些共享资源允许同时进行多个读的操作,但只允许一个写的操作,比如一个文件,只要其内容不变可以让多个线程同时读,不必做排他的锁定,排他的锁定只有在写的时候需要,以保证别的线程不会看到数据不完整的文件。这时候就需要使用读写锁。
[java]
view plain
copy
print?
/**
* 简单读写锁demo
* @author hejingyuan
*
*/
public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
//创建几个线程
for(int i=0;i<3;i++)
{
new Thread(){
public void run(){
while(true){
q3.get();
}
}
}.start();
new Thread(){
public void run(){
while(true){
q3.put(new Random().nextInt(10000));
}
}
}.start();
}
}
}
class Queue3{
private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据
//读写锁
ReadWriteLock rwl = new ReentrantReadWriteLock();
//读数据
public void get(){
rwl.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{
rwl.readLock().unlock();
}
}
//写数据
public void put(Object data){
rwl.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{
rwl.writeLock().unlock();
}
}
}
运行结果:
Thread-0 be ready to readdata!
Thread-2 be ready to readdata!
Thread-2have read data:null
Thread-0have read data:null
Thread-1 be ready towrite data!
Thread-1 have write data:1021
Thread-1 be ready towrite data!
Thread-1 have write data:2887
看到这里不免有人会问,既然读的时候可以多人访问,那么为什么还要加读锁呢?
答:当然要加锁了,否则在写时去读,可能不正确-(写的时候不能去读)
读写锁-模拟缓存系统实现:
[java]
view plain
copy
print?
public class CacheDemo {
private Map<String, Object> cache = new HashMap<String, Object>();
public static void main(String[] args) {
}
//定义读写锁
private ReadWriteLock rwl = new ReentrantReadWriteLock();
//读数据,使用读锁
public Object getData(String key){
//添加读锁
rwl.readLock().lock();
Object value = null;
try{
value = cache.get(key);
if(value == null){
//释放读锁
rwl.readLock().unlock();
//加上写锁
rwl.writeLock().lock();
try{
//假设三个线程同时去获取写锁,我们知道只有第一个线程能够获取
//那么其他两个线程只有等了,如果第一个线程按流程执行完后,刚才的两个线程可以得到写锁了,
//然后接着就可以修改数据了(赋值).所以加上判断!
if(value==null){//为什么还要判断?
value = "aaaa";//实际是去queryDB();
}
}finally{
//释放写锁
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
}finally{
rwl.readLock().unlock();
}
return value;
}
}
总结:
读写锁的作用为,当我们加上写锁时,其他线程被阻塞,只有一个写操作在执行,当我们加上读锁后,它是不会限制多个读线程去访问的。也就是get和put之间是互斥的,put与任何线程均为互斥,但是get与get线程间并不是互斥的。其实加读写锁的目的是同一把锁的读锁既可以与写锁互斥,读锁之间还可以共享。
[java]
view plain
copy
print?
/**
* 简单读写锁demo
* @author hejingyuan
*
*/
public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
//创建几个线程
for(int i=0;i<3;i++)
{
new Thread(){
public void run(){
while(true){
q3.get();
}
}
}.start();
new Thread(){
public void run(){
while(true){
q3.put(new Random().nextInt(10000));
}
}
}.start();
}
}
}
class Queue3{
private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据
//读写锁
ReadWriteLock rwl = new ReentrantReadWriteLock();
//读数据
public void get(){
rwl.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{
rwl.readLock().unlock();
}
}
//写数据
public void put(Object data){
rwl.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{
rwl.writeLock().unlock();
}
}
}
运行结果:
Thread-0 be ready to readdata!
Thread-2 be ready to readdata!
Thread-2have read data:null
Thread-0have read data:null
Thread-1 be ready towrite data!
Thread-1 have write data:1021
Thread-1 be ready towrite data!
Thread-1 have write data:2887
看到这里不免有人会问,既然读的时候可以多人访问,那么为什么还要加读锁呢?
答:当然要加锁了,否则在写时去读,可能不正确-(写的时候不能去读)
读写锁-模拟缓存系统实现:
[java]
view plain
copy
print?
public class CacheDemo {
private Map<String, Object> cache = new HashMap<String, Object>();
public static void main(String[] args) {
}
//定义读写锁
private ReadWriteLock rwl = new ReentrantReadWriteLock();
//读数据,使用读锁
public Object getData(String key){
//添加读锁
rwl.readLock().lock();
Object value = null;
try{
value = cache.get(key);
if(value == null){
//释放读锁
rwl.readLock().unlock();
//加上写锁
rwl.writeLock().lock();
try{
//假设三个线程同时去获取写锁,我们知道只有第一个线程能够获取
//那么其他两个线程只有等了,如果第一个线程按流程执行完后,刚才的两个线程可以得到写锁了,
//然后接着就可以修改数据了(赋值).所以加上判断!
if(value==null){//为什么还要判断?
value = "aaaa";//实际是去queryDB();
}
}finally{
//释放写锁
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
}finally{
rwl.readLock().unlock();
}
return value;
}
}
总结:
读写锁的作用为,当我们加上写锁时,其他线程被阻塞,只有一个写操作在执行,当我们加上读锁后,它是不会限制多个读线程去访问的。也就是get和put之间是互斥的,put与任何线程均为互斥,但是get与get线程间并不是互斥的。其实加读写锁的目的是同一把锁的读锁既可以与写锁互斥,读锁之间还可以共享。
相关文章推荐
- JAVA 并发编程-读写锁之模拟缓存系统(十一)
- JAVA 并发-多线程读写锁之模拟缓存系统(11)
- java中读写锁的实现及使用读写锁简单实现缓存系统的实例
- 银行业务调度系统-java并发程序模拟解决方案
- 【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列
- 转:【Java并发编程】之十一:线程间通信中notify通知的遗漏(含代码)
- (9)java5的线程【锁lock】与【读写锁_以及模拟缓存(妙用)】技术
- 并发编程学习:使用读写锁来编写高效率的缓存系统
- JAVA并发编程有界缓存的实现详解
- 【Java并发编程】之十一:线程间通信中notify通知的遗漏(含代码)(r)
- (十一)java并发编程--java.util.concurrent.Callable
- Java中读写锁的实现及使用读写锁简单实现缓存系统的实例
- 【Java并发编程】之十一:线程间通信中notify通知的遗漏(含代码)
- java 基于读写锁的缓存系统演示
- Python并发编程-Memcached (分布式内存对象缓存系统)
- c++并发编程,简单模拟飞机订票系统
- 【Java并发编程】之十一:线程间通信中notify通知的遗漏(含代码)
- Java并发编程基础构建模块(06)——高效缓存总结示例
- Java并发编程之为计算结果建立高效、可伸缩的高速缓存
- 设计高效的线程安全的缓存(java并发编程实战5.6)