2013-06-22 2 views
0

저는 실제 생활에서 흥미로운 문제에 직면하고 있습니다. 여기에 문제를 단순화했습니다 :스레드 안전 다중 생성자 질문

두 가지 방법 A()와 B 방법()을 디자인하십시오. 각 방법은 원소 원자 (A 또는 B)를 생성하는 것으로 생각할 수 있습니다. 화합물 A [N] B [M]은 N 개의 A 원자와 B 원자의 M을 필요로한다.

N 개의 A 원자와 M 개의 B 원자가 있기 전에 A()와 B()에 대한 각각의 호출이 차단됩니다. N 개의 A 원자와 M 개의 B 원자에 도달하면 첫 번째 N A() 호출과 첫 번째 M B() 호출이 반환됩니다. 예를 들어, N + 2 A() 호출을 수행하고 M B() 호출을 수행하면 첫 번째 N A() 호출과 모든 M B() 호출이 반환됩니다. 2 개의 A() 통화가 차단 된 상태로 유지됩니까?

어떻게이 문제를 해결할 수 있습니까? 자바를 사용하고 있습니다.

+0

이 들린다. 'countDown()'과'await()'메소드를 제공한다. – Gray

+0

필요없는 것의 반대입니까? 카운터가 0에 도달 할 때까지 CountDownLatch가 차단됩니다. – Pragmateek

답변

1

당신은 BlockingQueues 사용할 수 있습니다

static class AtomA 
{  
} 

static class AtomB 
{  
} 

static class ChemicalCompound 
{ 
    BlockingQueue<AtomA> as = new LinkedBlockingQueue<AtomA>(); 
    BlockingQueue<AtomB> bs = new LinkedBlockingQueue<AtomB>(); 

    public ChemicalCompound(int na, int nb) 
    { 
     while (na-- != 0) as.add(new AtomA()); 
     while (nb-- != 0) bs.add(new AtomB()); 
    } 

    public AtomA A() throws InterruptedException 
    { 
     return as.take(); 
    } 

    public AtomB B() throws InterruptedException 
    { 
     return bs.take(); 
    } 
} 

public static void main(String[] args) throws Exception 
{  
    final ChemicalCompound cc = new ChemicalCompound(2, 3); 

    Thread ta = new Thread(new Runnable(){ 
     @Override 
     public void run() 
     { 
      while (true) 
      { 
       try 
       { 
        cc.A(); 
        System.out.println("Got a A!"); 
        Thread.sleep(100); 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }   
    }); 
    ta.start(); 

    Thread tb = new Thread(new Runnable(){ 
     @Override 
     public void run() 
     { 
      while (true) 
      { 
       try 
       { 
        cc.B(); 
        System.out.println("Got a B!"); 
        Thread.sleep(100); 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }   
    }); 
    tb.start(); 

    ta.join(); 
    tb.join(); 

    return; 
} 

Thread.sleep를

스레드의 수 인터리빙을 입증하기위한 단지가 있지만, 물론 "생산"을 제거합니다.

결과 : 당신은`CountDownLatch` 클래스를 사용하여 할 필요가 같은

Got a A! 
Got a B! 
Got a A! 
Got a B! 
Got a B! 
+0

답장을 보내 주셔서 감사합니다.하지만이 방법이 효과가 없다고 생각합니다. 첫 번째 2 개의 A() 호출과 처음 3 개의 B() 호출을 차단해야합니다. 그러나 귀하의 코드가 첫 번째 2 A() 호출과 처음 3 B() 호출을 반환하고 나머지 호출이 차단되는 것처럼 보입니다. – CodeNoob

+0

예를 들어, N + 2 A() 호출을하고 MB() 호출을 수행하면 첫 번째 NA() 호출과 모든 MB() 호출이 반환됩니다. 두 개의 A() 호출이 남아있게됩니다 차단 되는가? * "이것은 정확히이 코드가하는 것입니다 : 두 개의 첫 번째 A와 세 개의 첫 번째 B 패스, 나머지는 차단됩니다. 따라서 * Gray *로 언급 된이 경우 CountDownLatch **를 사용할 수 있습니다. 실제 사용 케이스는 무엇입니까? – Pragmateek