欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java 使用ConcurrentHashMap和计数器实现锁

程序员文章站 2023-12-20 21:28:04
java 使用concurrenthashmap和计数器实现锁 在某些场景下,我们想让线程根据某些业务数据进行排队,简单代码如下: import java.ut...

java 使用concurrenthashmap和计数器实现锁

在某些场景下,我们想让线程根据某些业务数据进行排队,简单代码如下:

import java.util.arraylist;
import java.util.hashmap;
import java.util.list;
import java.util.map;
import java.util.concurrent.concurrenthashmap;
import java.util.concurrent.atomic.atomicinteger;

public class testserviceimpl {
  private static concurrenthashmap<long, lockobj> lockmap = new concurrenthashmap<long, lockobj>(40);

  public void test(long userid){
    lockobj lock = trylock(userid);
    synchronized (lock) {
      try{
        //处理业务
      }
      finally{
        unlock(lock);
      }
    }
  }

  private lockobj trylock(long key) {
    lockobj curval = new lockobj(key);
    lockobj preval = lockmap.putifabsent(key, curval);
    if (null == preval) {
      curval.inc();
      return curval;
    }
    else{
      preval.inc();
    }
    return preval;
  }

  private void unlock(lockobj lock){
    if (lock.dec() <= 0){
      lockmap.remove(lock.getkey());
    }
  }

  public class lockobj {
    private long key = 0;
    private atomicinteger count = new atomicinteger(0);

    public lockobj(long key){
      this.key = key;
    }

    public int inc(){
      return count.incrementandget();
    }
    public int dec(){
      return count.decrementandget();
    }

    public long getkey(){
      return key;
    }

    @override
    public string tostring() {
      return "lockobj [key=" + key + ", count=" + count + "]";
    }
  }

}

按照userid来排队,如果每个线程处理数据后不释放锁的话,那么可以不利用计数器。但是加了释放锁的操作,则必须加上计算器。因为当线程把锁释放掉后,还没来得及退出synchronized 代码块时,另外一个线程调用了trylock方法,那该线程将拿到另外一个对象的锁,导致利用synchronized 关键字进行userid排队失败。

也可以利用guava的api来实现。

import com.google.common.collect.interner;
import com.google.common.collect.interners;


public class testserviceimpl {

  interner<string> pool = interners.newweakinterner();

  public void test(long userid) throws ospexception {

    synchronized ( pool.intern(string.valueof(userid))){
      //处理业务操作
    }
  }
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

上一篇:

下一篇: