Java-No.06 读写锁控制缓存失效照成的Dogpile效应

package cn.guagua.mobile.common;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.log4j.Logger;

import cn.guagua.mobile.cache.redis.Redis;

/**
 * 读写锁控制强制读取缓存同步
 * @author shma
 * @date 2014-10-11 15:04:28
 */
public class SynchCacheLock<T> {

	private static final Logger logger = Logger.getLogger(SynchCacheLock.class);

	private static Redis.RedisClient redis1 = new Redis.RedisClient("1");

	private ReadWriteLock lock = null;
	private Lock readLock = null; // 读锁
    private Lock writeLock = null; // 写锁

	public SynchCacheLock() {
		lock = new ReentrantReadWriteLock();
		readLock = lock.readLock();
		writeLock = lock.writeLock();
		System.out.println(Thread.currentThread().getName() + ">>> cache lock init...");
	}

	public T getCache(String key, Runnable task) {
		T obj = null;
		readLock.lock();
		try {
			obj = (T) redis1.getObject(key);
			if(obj == null) {
				System.out.println(Thread.currentThread().getName() + " read request " + key + " is null, wait query...");
				readLock.unlock();
				writeLock.lock();
				try {
					obj = (T) redis1.getObject(key);
					if(obj == null) {
						task.run();//强制执行执行写缓存任务
						System.out.println(Thread.currentThread().getName() + " read request " + key + " end...");
						obj = (T) redis1.getObject(key);
					}
				} catch(Throwable e) {
					System.out.println("readLock error...");
					e.printStackTrace();
				} finally {
					readLock.lock();
		            writeLock.unlock();
				}
			}
			System.out.println(Thread.currentThread().getName() + " read request " + key + " data...");
		} catch(Throwable e) {
			System.out.println("lock error...");
			e.printStackTrace();
		} finally {
			readLock.unlock();
		}

		return obj;
	}
}
时间: 2024-10-13 16:19:51

Java-No.06 读写锁控制缓存失效照成的Dogpile效应的相关文章

JAVA 并发编程-读写锁之模拟缓存系统(十一)

在多线程中,为了提高效率有些共享资源允许同时进行多个读的操作,但只允许一个写的操作,比如一个文件,只要其内容不变可以让多个线程同时读,不必做排他的锁定,排他的锁定只有在写的时候需要,以保证别的线程不会看到数据不完整的文件.这时候就需要使用读写锁. /** * 简单读写锁demo * @author hejingyuan * */ public class ReadWriteLockTest { public static void main(String[] args) { final Queu

java中ReentrantReadWriteLock读写锁的使用

ReentrantReadWriteLock读写锁的使用 Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可.如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁:如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁.总之,读的时候上读

java并发编程-读写锁

最近项目中需要用到读写锁 读写锁适用于读操作多,写操作少的场景,假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源.但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写,也就是说 读-读能共存,读-写不能共存,写-写不能共存 我们直接使用java的读写锁  ReadWriteLock 如下代码是使用缓存的典型场景: public class ReadW

java中的读/写锁

读写锁接口:ReadWriteLock,它的具体实现类为:ReentrantReadWriteLock 使用场景: 对于一个资源,读读能共存,读写不能共存,写写不能共存. 锁降级:从写锁变成读锁: 锁升级:从读锁变成写锁. ReentrantReadWriteLock不支持锁升级,支持锁降级 ReadWriteLock rtLock = new ReentrantReadWriteLock(); rtLock.readLock().lock(); System.out.println("get

22、Java并发性和多线程-Java中的读/写锁

以下内容转自http://ifeve.com/read-write-locks/: 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些.假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源.但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存).这就需要一个读/

java多线程 -- ReadWriteLock 读写锁

写一条线程,读多条线程能够提升效率. 写写/读写 需要"互斥";读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁可以由多个 reader 线程同时保持.写入锁是独占的. ReadWriteLock 读取操作通常不会改变共享资源,但执行写入操作时,必须独占方式来获取锁.对于读取操作占多数的数据结构. ReadWriteLock 能提供比独占锁更高的并发性.而对于只读的数据结构,其中包含的不变性可以完全

[转]高并发访问下避免对象缓存失效引发Dogpile效应

避免Redis/Memcached缓存失效引发Dogpile效应 Redis/Memcached高并发访问下的缓存失效时可能产生Dogpile效应(Cache Stampede效应). 推荐阅读:高并发下的 Nginx 优化方案 http://www.linuxidc.com/Linux/2013-01/78791.htm 避免Memcached缓存的Dogpile效应 Memcached的read-through cache流程:客户端读取缓存,没有的话就由客户端生成缓存.Memcached缓

Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

synchronized 是互斥锁: lock 更广泛,包含了读写锁 读写锁特点: 1)多个读者可以同时进行读2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者) 互斥锁特点: 一次只能一个线程拥有互斥锁,其他线程只有等待 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronize

Java并发编程之重入锁与读写锁

重入锁 重入锁,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁阻塞,该特性的实现需要解决以下两个问题. 1.线程再次获取锁.锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取. 2.锁的最终释放.线程重复n次获取了锁,随后在第n次释放该锁后,其他线程能够获取到该锁.锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁被重复获取的次数,而锁被释放时,计数自减,当计数等于0时表示锁已经成功释放