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);
    }
}



  1. package test;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import java.util.Random;  
  6. import java.util.concurrent.locks.ReadWriteLock;  
  7. import java.util.concurrent.locks.ReentrantReadWriteLock;  
  8.   
  9. /** 
  10.  * 设计一个缓存系统 
  11.  * 读写锁的应用。 
  12.  * JDK1.5自带的读写锁特性,读与读不互斥,读与写互斥,写与写互斥。 
  13.  * 为什么要使用读写锁?一句话概括那就是提高系统性能,如何提高呢? 
  14.  * 试想,对于所有对读的操作是不需要线程互斥的,而如果方法内 
  15.  * 使用了synchronized关键字同步以达到线程安全,对于所有的线程不管是读还是写的操作都要同步。 
  16.  * 这时如果有大量的读操作时就会又性能瓶颈。 
  17.  *  
  18.  * 所以,当一个方法内有多个线程访问,并且方法内有读和写读操作时, 
  19.  * 提升性能最好的线程安全办法时采用读写锁的机制对读写互斥、写写互斥。这样对于读读就没有性能问题了 
  20.  * @author zhurudong 
  21.  * 
  22.  */  
  23. public class CacheTest {  
  24.   
  25.     // 缓存的map  
  26.     private Map<String, Object> map = new HashMap<String, Object>();  
  27.     // 读写锁对象  
  28.     private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();  
  29.       
  30.     /** 
  31.      * 从缓存中获取数据的方法 
  32.      * @param key 
  33.      * @return 
  34.      */  
  35.     public Object getData(String key) {  
  36.         readWriteLock.readLock().lock();//读锁,只对写的线程互斥  
  37.         Object value = null;  
  38.         try {  
  39.             // 尝试从缓存中获取数据  
  40.             value = map.get(key);  
  41.             if (value == null) {  
  42.                 readWriteLock.readLock().unlock();//发现目标值为null,释放掉读锁  
  43.                 readWriteLock.writeLock().lock();//发现目标值为null,需要取值操作,上写锁  
  44.                 try {  
  45.                     value = map.get(key);// 很严谨这一步。再次取目标值  
  46.                     if (value == null) {//很严谨这一步。再次判断目标值,防止写锁释放后,后面获得写锁的线程再次进行取值操作  
  47.                         // 模拟DB操作  
  48.                         value = new Random().nextInt(10000) + "test";  
  49.                         map.put(key, value);  
  50.                           
  51.                         System.out.println("db completed!");  
  52.                     }  
  53.                     readWriteLock.readLock().lock();//再次对读进行锁住,以防止写的操作,造成数据错乱  
  54.                 } finally {  
  55.                     /* 
  56.                      * 先加读锁再释放写锁读作用: 
  57.                      * 防止在43行出多个线程获得写锁进行写的操作,所以在写锁还没有释放前要上读锁 
  58.                      */  
  59.                     readWriteLock.writeLock().unlock();  
  60.                 }  
  61.             }  
  62.               
  63.         } finally {  
  64.             readWriteLock.readLock().unlock();  
  65.         }  
  66.         return value;  
  67.     }  
  68.       
  69.     /** 
  70.      *  test main 
  71.      * @param args 
  72.      */  
  73.     public static void main(String[] args) {  
  74.         final CacheTest cache = new CacheTest();  
  75.         final String key = "user";  
  76.         for (int i = 0; i < 1000; i++) {  
  77.             new Thread(){  
  78.                 public void run() {  
  79.                     System.out.println(cache.getData(key));  
  80.                 };  
  81.             }.start();  
  82.         }  
  83.     }  




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 {
    privateMap<String, Object> cache = newHashMap<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;
//  }
    //可重入锁的设计
    staticReadWriteLock rwl = newReentrantReadWriteLock();
    publicsynchronized 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();
        }
        returnvalue;
    }
     
    publicstatic void main(String[] args) {
         
    }
}

0 0