2017-12-26 2 views
1

아주 똑똑한 방법으로 잠글 필요가있는 코드가 있습니다. 기본적으로 일부 텍스트 파일을 업데이트하는 일부 http 요청을 수행하는 코드 섹션을 잠글 필요가 있다고 가정 해 봅니다.Java 스마트 잠금 메커니즘

이 작업은 이름별로 주어진 파일에서 작동 할 수 있습니다.

내 의사 :

public void UpdateFile(int id){ 
    dal.invokeHTTPutRequest(id, fileContent); 
} 

이 코드는 잠금은 지정된 ID에 대한 일어날 것

  1. 하는 방식으로 동기화/잠금되고 싶어요. 따라서 id 1이 요청되고 id 1에 대한 다른 요청이 요청되면 대기하게됩니다. 그러나 ID 2에 대한 요청이 도착하면 기다리지 않습니다.

  2. 시간 초과가 너무 많아서 많은 요청이 도착하면 예외가 발생하므로 많은 시간이 걸립니다.

아이디어가 있으십니까?

답변

0

간단한 해결책은 Java ReentrantLock의 HashMap을 사용하는 것입니다. 해시 맵에서 파일을 키로 사용하여 relentvent reentrantlock을 검색 할 수 있습니다.

1

글쎄, 그것은 (예 : 레디 스 등) 데이터베이스 또는 캐시에 의해 구현 분산 잠금 또는 다른 쿼럼 미들웨어 (예 : 사육사와 같은 및 ETCD)

여기 구아바에 따라 다른 미들웨어없이 간단한 구현을 제공에서 흔한 일 :

import com.google.common.cache. *;

import java.util.concurrent.ExecutionException; 
import java.util.concurrent.TimeUnit; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

public class LockUtil { 
    private static final LoadingCache<Integer, Lock> lockCache = CacheBuilder.newBuilder().maximumSize(Long.MAX_VALUE).build(new CacheLoader<Integer, Lock>() 
      { 
       @Override 
       public Lock load(Integer i) 
       { 
        return new ReentrantLock(); 
       } 
      }); 

    public static Lock getLock(int id) throws ExecutionException { 
     return lockCache.get(id); 
    } 
} 

대신 ConcurrentHashMap을 사용할 수 있습니다.

그리고 제한 시간

, 당신은 대신 잠금 장치의 설정된 tryLock (타임 아웃)를 사용할 수 있습니다()

0

나는 동기화 모니터 개체를 가져 문자열 풀을 시도했다. 나를

import java.util.*; 
    import java.util.concurrent.*; 

    public class Test { 

    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { 
      List<Callable<String>> taskList = new ArrayList<>(); 
      taskList.add(() -> abcd(1)); 
      taskList.add(() -> abcd(3)); 
      taskList.add(() -> abcd(1)); 
      taskList.add(() -> abcd(1)); 
      ExecutorService executor = Executors.newFixedThreadPool(4); 
      executor.invokeAll(taskList); 
     } 

     private static String abcd(int id) throws InterruptedException { 
      synchronized (String.valueOf(id).intern()){ 
      System.out.println(id +" - "+Thread.currentThread().getId()); 
      Thread.sleep(2000l); 
      } 
      return String.valueOf(id); 
     } 

    } 

는이

public void UpdateFile(int id) { 
     synchronized (String.valueOf(id).intern()) { 
     dal.invokeHTTPutRequest(id, fileContent); 
     } 
    } 
처럼 사용할 수있는 희망이 구현에 대해 언급하시기 바랍니다 괜찮을 것 같다