2013-02-26 2 views
0

저는 Java에 매우 익숙합니다. 멀티 스레드입니다.Java에서 Countdownlatch 및 Executor를 사용하는 중에 예상 출력이 나타나지 않습니다.

0 Printing .... 1 L 10 
0 Printing .... 2 L 10 
0 Printing .... 3 L 10 
0 Printing .... 4 L 10 
0 Printing .... 5 L 10 
0 Printing .... 6 L 10 
0 Printing .... 7 L 10 
0 Printing .... 8 L 10 
0 Printing .... 9 L 10 
0 Printing .... 10 L 10 

다음 흐름이 기다리고 계속 같다 - 자바 스레딩에 CountDownLatch를하고 집행을 배우려고 노력하고하는 것은 앞으로 다음과 같은 코드 -

import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class ExecutorBasicFramework { 


    class MyThread extends Thread{ 

     int iCount ; String name; 
     CountDownLatch latch; 

     public MyThread(int iCount, String name, CountDownLatch latch) { 
      super(); 
      this.iCount = iCount; 
      this.name = name; 
      this.latch = latch;   
     } 

     @Override 
     public void run() { 
      for(int i=0;i<10;i++){ 
       System.out.println(name+" Printing .... "+ ++iCount+" L "+latch.getCount()); 
       try { 
        Thread.sleep(100); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       }    
      } 
      latch.countDown(); 

     } 

    } 

    public ExecutorBasicFramework() { 
     createThread(); 
    } 


    private void createThread() { 
     ExecutorService exec = Executors.newFixedThreadPool(10); 
     CountDownLatch latch = new CountDownLatch(10); 
     for(int i=0;i<10;i++){   
      MyThread thread = new MyThread(i*10, ""+i,latch); 
      exec.execute(thread); 

      try { 
       latch.await(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     exec.shutdownNow();  

    } 

    public static void main(String[] args) { 
     new ExecutorBasicFramework(); 
    } 

} 

출력은 그대로 구현했습니다. 내 예상 출력은 위와 비슷하지만 0을 인쇄 한 후 비슷한 출력을 1에서 9까지 인쇄 한 다음 프로그램을 중지해야합니다.

나는 카운트 다운 래치가 기다리고 기다리는 중이고 실행 프로그램의 다음 카운터를 증가시키지 않을 것이라고 생각한다. 그래서 나는 예상되는 결과물을 얻을 수 없다. 내가 기대하고 출력처럼 - 래치 각각 감소 카운터와

0 Printing .... 1 L 10 
0 Printing .... 2 L 10 
0 Printing .... 3 L 10 
0 Printing .... 4 L 10 
0 Printing .... 5 L 10 
0 Printing .... 6 L 10 
0 Printing .... 7 L 10 
0 Printing .... 8 L 10 
0 Printing .... 9 L 10 
0 Printing .... 10 L 10 


1 Printing .... 11 L 9 
1 Printing .... 12 L 9 
1 Printing .... 13 L 9 
1 Printing .... 14 L 9 
1 Printing .... 15 L 9 
1 Printing .... 16 L 9 
1 Printing .... 17 L 9 
1 Printing .... 18 L 9 
1 Printing .... 19 L 9 
1 Printing .... 20 L 9 

and So on ... 
2 Printing .... 21 L 8 
2 Printing .... 22 L 8 
2 Printing .... 23 L 8 

, 다음 스레드는 프로세스를 다시 풀 10까지 카운트를 실행해야합니다 후 다시 래치 카운터를 감소해야이다 스레드 9가 완료 될 때까지 반복합니다. 동일

일부 입력을 제안하십시오.

+0

모든 작업이 완료 될 때까지 기다리시겠습니까? 여기 목표는 무엇입니까? – Gray

답변

1

, 당신은 스레드를 제출하는 latch.await() 외부 루프를 이동해야합니다. 또한 중단 된 플래그를 다시 설정하지 않고 InterruptedException을 먹지 않아야합니다. (see this article).

보정은 다음과 같이 보일 것이다 :

for(int i=0;i<10;i++){   
    MyThread thread = new MyThread(i*10, ""+i,latch); 
    exec.execute(thread); 
} 
try { 
    latch.await(); 
} catch (InterruptedException e) { 
    Thread.currentThread().interrupt(); 
} 

이 확실히 작동하지만, 래치는 ExecutorService를 사용하는 경우 다른 스레드에서의 Runnable의 실행을 기다리는 차선의 방법입니다. execute()이 아닌 submit()을 사용하는 경우 Futuresubmit()으로 반환되면 제출 된 Runnable이 완료 될 때까지 get()으로 대기 할 수 있습니다.

3

따라서 카운트 다운 값을 10 new CountDownLatch(10)으로 구성했지만 코드가 스레드 당 한 번만 감소합니다. 당신은 단지 하나 개의 스레드를 포크 후에는 래치 대기 그러나 당신이 의도 9.

MyThread thread = new MyThread(i*10, ""+i,latch); 
exec.execute(thread); 
latch.await(); 

확실하지에 앉아있다하지만 어쩌면 latch.countDown(); 스레드에서 루프 내부 을해야 하는가? 목표는 완료 모든 작업을 기다리는 경우

for(int i=0;i<10;i++) { 
    ... 
    // if you want the latch to count-down 10 times, it should be inside the loop 
    latch.countDown(); 
} 
// it should not go here, outside the loop 

, 당신은 ExecutorService.awaitTermination(...) 방법으로이 작업을 수행 할 수 있습니다 또한

// submit jobs in loop 
exec.shutdown(); 
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 

, 당신은 MyThreadThread을 확장되어서는 안된다 수업. Runnable을 구현해야합니다. 코드가 작동하는 유일한 이유는 ThreadRunnable이지만 MyThread을 구현해야한다는 것입니다.이 아닌 경우 이 Thread이되어야합니다. ExecutorService은 또는 Callable이 아니라 Thread이 아닙니다. 내부적으로 서비스에 대한 스레드를 관리합니다. 당신의 의도는 모든 스레드가 실행될 때까지 main() 방법 대기를 위해 CountDownLatch를 사용하는 경우

+0

예상 출력을 업데이트했으며 실행 가능에 관한 제안에 감사드립니다. –

+1

@ 그레이는 여기에 백만 번을 말했음에 틀림 없어 :) –

+0

안돼 @RalfH. 100k상의! ;-) – Gray

0

입력 해 주셔서 감사합니다. 내가 기대 한 것을 얻기위한 쉬운 해결책이 하나 더 있음을 발견했습니다. 난 그냥 Executors.newSingleThreadExecutor();을 사용 했으므로 모든 작업이 순차적으로 구현되도록 보장합니다.

관련 문제