2012-09-04 3 views
2

데이터베이스 연결 풀과 같은 리소스 풀을 구현하려는 경우. 어떤 동시 수집을 사용 하시겠습니까? BlockingQueue 또는 Semaphore?BlockingQueue 대 Semaphore

생산자 - 소비자 디자인 패턴과 마찬가지로 BlockingQueue의 경우 생산자는 모든 연결을 대기열에 배치하고 소비자는 대기열에서 다음에 사용 가능한 연결을 취합니다.

Semaphore의 경우 세마포어를 풀 크기로 지정하고 풀 크기에 도달 할 때까지 허가를 얻고 그 중 누구라도 허가를 해제하고 풀에 자원을 넣을 때까지 기다립니다.

어느 것이 더 간단하고 쉽습니까? 우리는 하나만 사용할 수 있지만 다른 것은 사용할 수없는 시나리오는 무엇입니까?

+1

BlockingQueue에 요청을하지 않으려면 _connections_를 BlockingQueue에 넣습니다. – jtahlborn

+0

맞습니다. 저를 업데이트 해주세요. – peter

답변

12

BlockingQueue는 Connections/리소스도 추적하므로 더 간단합니다.

public abstract class ResourcePool<Resource> { 
    private final BlockingQueue<Resource> free; 

    protected ResourcePool(int freeLimit) { 
     free = new ArrayBlockingQueue<>(freeLimit); 
    } 

    public Resource acquire() { 
     Resource resource = free.poll(); 
     return resource == null ? create() : resource; 
    } 

    public void recycle(Resource resource) { 
     if (!free.offer(resource)) 
      close(resource); 
    } 

    protected abstract Resource create(); 

    protected abstract void close(Resource resource); 
} 

당신이 볼 수 있듯이

는 BlockingQueue의 무료 리소스를 추적하고 너무 많은 리소스가없는 데 도움이됩니다. 명시 적 잠금을 요구하지 않고 스레드로부터 안전합니다. 당신이 세마포어를 사용하는 경우

, 당신은 여전히 ​​컬렉션의 자원을 저장해야합니다 (세마포어 중복을)

+1

참으로 좋은 점 - 어떻게 연결을 되 찾을 수 있습니까? (더 이상 사용하지 않을 때) 어떻게 되나요? – assylias

+1

@assylias 예제를 추가했습니다. –

0

많은 차단 큐, 어쨌든 세마포어로 구현된다 (그리고 어쩌면 뮤텍스/퓨 텍스/CS) . 객체 저장소에 대한 차단 대기열을 많이 사용합니다. 일단 작동하는 차단 대기열이 있으면 객체 풀에 대해 다른 용도로 사용하는 이유는 무엇입니까?

0

고급 연결 풀의 경우 아마도 둘 다 사용하지 않을 것입니다. @PeterLawrey가 지적했듯이 BlockingQueue는 모든 리소스가 처음 존재하는 단순한 풀에 가장 적합합니다. 그러나 필요에 따라 리소스를 생성하는 것처럼 더 복잡한 작업을 수행하려는 경우 추가 동시성 구조가 필요할 가능성이 큽니다. 이 경우 가장 간단한 동기화 된 블록이나 잠금을 사용하게 될 가능성이 높습니다.

관련 문제