Heim  >  Artikel  >  Java  >  Detaillierte Erklärung, wie Java ConcurrentHashMap und Zähler verwendet, um Sperren zu implementieren

Detaillierte Erklärung, wie Java ConcurrentHashMap und Zähler verwendet, um Sperren zu implementieren

黄舟
黄舟Original
2017-05-28 09:12:342432Durchsuche

In diesem Artikel werden hauptsächlich relevante Informationen über die Verwendung von ConcurrentHashMap und Counter zum Implementieren von Sperren vorgestellt. Freunde in Not können sich auf

Java beziehen Verwenden Sie ConcurrentHashMap und Zähler, um Sperren zu implementieren.

In einigen Szenarien möchten wir, dass Threads gemäß bestimmten Geschäftsdaten in die Warteschlange gestellt werden. Der einfache Code lautet wie folgt:

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

}

Warteschlange entsprechend zu userId Wenn jeder Thread die Sperre nach der Verarbeitung der Daten nicht aufhebt, muss der Zähler nicht verwendet werden. Wenn Sie jedoch den Vorgang zum Lösen der Sperre hinzufügen, müssen Sie einen Taschenrechner hinzufügen. Denn nachdem der Thread die Sperre aufgehoben hat, bevor er Zeit hat, den synchronisierten Codeblock zu zu verlassen, ruft ein anderer Thread die tryLock-Methode auf, dann erhält der Thread die Sperre eines anderen Objekts, As Dies führt dazu, dass das Einreihen der Benutzer-ID in die Warteschlange mit dem synchronisierten Schlüsselwort fehlschlägt.

kann auch mit der API von guava implementiert werden.

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

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung, wie Java ConcurrentHashMap und Zähler verwendet, um Sperren zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn