java通过缓存实现同步锁
来源:互联网 发布:大数据下的市场营销 编辑:程序博客网 时间:2024/06/07 16:52
//极验注册分值>=90,跳到错误页面,提示语:该手机号暂时无法在线注册,请联系客服。
String mobile = request.getMobile();// 加锁的KEY
String lockKey = LvtuClientMemCacheConstants.USUAL_CACHEKEY_CONSTANTS.MYLVMM_LVTU_LOGIN_REGISTER_LOCK.getCacheKey() + mobile;
try {
// 时候锁定成功,true-锁定成功;false-锁定失败
boolean isLock = LvtuMemcachedUtil.getInstance().tryLock(lockKey, LOCK_SECCONDS, TRYLOCK_TIMEOUT_SECONDS);
// 加锁失败,则直接报错
if(!isLock) {
UserRegisterSSOResponse response = new UserRegisterSSOResponse();
response.setMessage("正在处理..");
response.setErrorMessage("表单重复提交,手机号:" + mobile);
logger.error("表单重复提交,手机号:" + mobile);
return response;
}
long rainScore = getRainScores(mobile);
。。。。。。。。。。。。。。。。
public boolean tryLock(String lockKey) {
return tryLock(lockKey, DBConfig.DEFAULT_LOCK_SECCONDS, DBConfig.DEFAULT_TRYLOCK_TIMEOUT_SECONDS);
}
public boolean tryLock(String lockKey, int lockSec, int timeOutSec) {
MemCachedClient client = getMemCachedClient(false);
long start = System.currentTimeMillis();
while (true) {
boolean locked = client.add(lockKey, "", getDateAfter(lockSec));
if (locked) {
return true;
} else {
long now = System.currentTimeMillis();
long costed = now - start;
if (costed >= timeOutSec * 1000) {
return false;
}
}
}
}
/**
* 该锁是否已被持有 false:未被持有,true:已被持有
*
* @param lockKey
* @param lockSec
* @return
*/
public boolean isHoldLock(String lockKey, int lockSec) {
boolean isHoldLock = false;
MemCachedClient client = getMemCachedClient(false);
boolean locked = client.add(lockKey, "holded", getDateAfter(lockSec));
if (!locked) {
isHoldLock = true;
}
return isHoldLock;
}
public boolean releaseLock(String lockKey) {
MemCachedClient client = getMemCachedClient(false);
return client.delete(lockKey);
}
}
- package test;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Random;
- import java.util.concurrent.locks.ReadWriteLock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- /**
- * 设计一个缓存系统
- * 读写锁的应用。
- * JDK1.5自带的读写锁特性,读与读不互斥,读与写互斥,写与写互斥。
- * 为什么要使用读写锁?一句话概括那就是提高系统性能,如何提高呢?
- * 试想,对于所有对读的操作是不需要线程互斥的,而如果方法内
- * 使用了synchronized关键字同步以达到线程安全,对于所有的线程不管是读还是写的操作都要同步。
- * 这时如果有大量的读操作时就会又性能瓶颈。
- *
- * 所以,当一个方法内有多个线程访问,并且方法内有读和写读操作时,
- * 提升性能最好的线程安全办法时采用读写锁的机制对读写互斥、写写互斥。这样对于读读就没有性能问题了
- * @author zhurudong
- *
- */
- public class CacheTest {
- // 缓存的map
- private Map<String, Object> map = new HashMap<String, Object>();
- // 读写锁对象
- private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
- /**
- * 从缓存中获取数据的方法
- * @param key
- * @return
- */
- public Object getData(String key) {
- readWriteLock.readLock().lock();//读锁,只对写的线程互斥
- Object value = null;
- try {
- // 尝试从缓存中获取数据
- value = map.get(key);
- if (value == null) {
- readWriteLock.readLock().unlock();//发现目标值为null,释放掉读锁
- readWriteLock.writeLock().lock();//发现目标值为null,需要取值操作,上写锁
- try {
- value = map.get(key);// 很严谨这一步。再次取目标值
- if (value == null) {//很严谨这一步。再次判断目标值,防止写锁释放后,后面获得写锁的线程再次进行取值操作
- // 模拟DB操作
- value = new Random().nextInt(10000) + "test";
- map.put(key, value);
- System.out.println("db completed!");
- }
- readWriteLock.readLock().lock();//再次对读进行锁住,以防止写的操作,造成数据错乱
- } finally {
- /*
- * 先加读锁再释放写锁读作用:
- * 防止在43行出多个线程获得写锁进行写的操作,所以在写锁还没有释放前要上读锁
- */
- readWriteLock.writeLock().unlock();
- }
- }
- } finally {
- readWriteLock.readLock().unlock();
- }
- return value;
- }
- /**
- * test main
- * @param args
- */
- public static void main(String[] args) {
- final CacheTest cache = new CacheTest();
- final String key = "user";
- for (int i = 0; i < 1000; i++) {
- new Thread(){
- public void run() {
- System.out.println(cache.getData(key));
- };
- }.start();
- }
- }
- }
Java中的读写锁:
多个读锁不互斥, 读锁与写锁互斥, 写锁与写锁互斥, 这是由JVM自行控制的,我们只要上好相应的锁即可。
package
com.cn.gbx;
import
java.util.HashMap;
import
java.util.Map;
import
java.util.concurrent.locks.ReadWriteLock;
import
java.util.concurrent.locks.ReentrantReadWriteLock;
public
class
CacheDesign {
private
Map<String, Object> cache =
new
HashMap<String, Object>();
//对象锁的设计
// public synchronized Object getData(String key){
// Object value = null;
// value = cache.get(key);
// if (value == null) {
// value = "queryDao";
// cache.put(key, value);
// }
// return value;
// }
//可重入锁的设计
static
ReadWriteLock rwl =
new
ReentrantReadWriteLock();
public
synchronized
Object getData(String key){
Object value =
null
;
rwl.readLock().lock();
try
{
value = cache.get(key);
if
(value ==
null
) {
rwl.readLock().unlock();
rwl.writeLock().lock();
try
{
if
(value ==
null
) {
//确保后边的线程不会重读写
value =
"queryDao"
;
cache.put(key, value);
}
}
finally
{
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
}
finally
{
rwl.readLock().unlock();
}
return
value;
}
public
static
void
main(String[] args) {
}
}
- java通过缓存实现同步锁
- Java通过缓存队列执行任务代码实现
- tokyo tyrant实现缓存同步
- 线程的同步:通过同步方法实现
- ehcache通过注解实现缓存
- 通过ConcurrentHashMap实现本地缓存
- 通过JSONP 实现同步登录
- 实现缓存 java实现
- MySQL UDF实现缓存数据同步
- java后台数据库同步使用map进行缓存
- java同步锁-实现买火车票
- JAVA实现分布式缓存
- JAVA缓存的实现
- JAVA缓存的实现
- JAVA缓存的实现
- 用JAVA实现缓存
- java实现缓存
- JAVA缓存的实现
- PHP魔术方法 __sleep和__wakeup()
- java 中文转英文性能最快
- 微信支付总结
- Ubuntu12.04下配置环境变量
- ubuntu camera view
- java通过缓存实现同步锁
- java集合详解
- 解决nginx反向代理django应用非80端口,跳转错误的问题
- android TV开发:使用RecycleView实现横向的Listview并响应点击事件
- Python异常处理
- 第十一讲项目1-分离各位数
- ida 与 olldbg 神同步插件labeless
- HDU2076 时钟夹角
- LBP-(Texture) Local Binary Patterns