Maison > Java > javaDidacticiel > le corps du texte

Explication détaillée de la façon dont Java utilise ConcurrentHashMap et les compteurs pour implémenter les verrous

黄舟
Libérer: 2017-05-28 09:12:34
original
2507 Les gens l'ont consulté

Cet article présente principalement les informations pertinentes sur Java utilisant ConcurrentHashMap et counter pour implémenter des verrous. Les amis dans le besoin peuvent se référer à

java. Utilisez ConcurrentHashMap et les compteurs pour implémenter des verrous

Dans certains scénarios, nous souhaitons que les threads soient mis en file d'attente en fonction de certaines données commerciales. Le code simple est le suivant :

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

}
Copier après la connexion

File d'attente selon. à userId , Si chaque thread ne libère pas le verrou après le traitement des données, le compteur n'a pas besoin d'être utilisé. Mais si l'on ajoute l'opération de déverrouillage, il faut ajouter un calculateur. Parce qu'après que le thread a libéré le verrou, avant d'avoir le temps de sortir du bloc de code synchronisé, un autre thread appelle la méthode tryLock, puis le thread obtiendra le verrou d'un autre objet, comme par conséquent, la mise en file d'attente userId à l'aide du mot clé synchronisé échoue.

peut également être implémenté à l'aide de l'API de Guava.

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))){
      //处理业务操作
    }
  }
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal