Home  >  Article  >  Java  >  Detailed explanation of how java uses ConcurrentHashMap and counters to implement locks

Detailed explanation of how java uses ConcurrentHashMap and counters to implement locks

黄舟
黄舟Original
2017-05-28 09:12:342479browse

This article mainly introduces the relevant information about java using ConcurrentHashMap and counter to implement locks. Friends in need can refer to

java Use ConcurrentHashMap and counter to implement lock

In some scenarios, we want threads to be queued according to certain business data. The simple code is as follows:

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 + "]";
    }
  }

}

Queue according to userId, if If each thread does not release the lock after processing the data, then the counter does not need to be used. But if the operation of releasing the lock is added, a calculator must be added. Because after the thread releases the lock, before it has time to exit the synchronized code block, another thread calls the tryLock method, then the thread will get the lock of another object, As a result, userId queuing using the synchronized keyword fails.

You can also use guava’s API to achieve this.

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))){
      //处理业务操作
    }
  }
}

The above is the detailed content of Detailed explanation of how java uses ConcurrentHashMap and counters to implement locks. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn