2010-02-14 2 views
3

스레드를 실행하는 방법(). 기본적으로 나는 2 개의 스레드 T1 및 T2가 있고 다음 순서로 실행되도록합니다.스레드 동기화 - 나는 문제와 관련된 스레드 통신 사용 대기()를 해결하고 알리도록 노력 해왔다 대안으로

T1, T2, T1, T2 ..... 어떻게 달성 할 수 있습니까?

실제 문제 : 홀수 (예 : 1 - 100) 및 짝수 (1 - 100)를 인쇄하는 T2 - 2 개의 스레드 T1이 있습니다. 이제 출력은 1, 2, 3, 4, 5, ...이어야합니다. 100

+3

단일 스레드에서 작업을 실행 하시겠습니까? –

+0

뭔가 동기화하고 싶다면 왜 스레드로 실행하고 있습니까? – Guy

+0

두 스레드가 생성됩니다. 먼저 실행 된 첫 번째 스레드와 교대로 실행되도록하십시오. –

답변

2

당신은 생산자 - 소비자 패턴을 설명합니다.

Java 구현은 M. Grand의 "Patterns in Java. Volume 1"과 "Java 2 : The Complete Reference"(Naughton and Schildt)를 포함한 수많은 자바 서적에 설명되어 있습니다.

기본 아이디어 : 두 스레드 모두 모니터 1 개를 사용해야합니다 (즉, 해당 코드는 synchronized(monitor) {} 블록 안에 있어야합니다). 또한 두 개의 스레드 중 어느 것이 현재 작동해야하는지 나타내는 플래그 변수가 필요합니다.

당신의 스레드 중 하나가 내부 블록을 동기화 할 때 그것은 일을하기 위해 자신의 차례 여부 플래그 변수를 확인해야합니다. 그렇다면 작동시키고 플래그 값을 변경 한 다음 대기중인 모든 스레드에 알립니다. 그렇지 않다면 기다려야합니다. java.util.concurrent의 패키지에

+0

정확히는 아닙니다.기본적으로 나는 2 개의 스레드를 가지고 있으며, 하나는 인쇄하고 다른 하나는 b를 인쇄한다고 말할 수 있습니다. 이제 시퀀스 ababab ..... –

+2

@ sai를 출력하고 싶습니다.이를 위해 솔루션을 생산자 - 소비자에게 사용할 수 있습니다. –

1

다단계 프로세스를 병렬 처리하려고합니까? 그렇다면 내 대답 here을 참조하고이를 수행하기위한 몇 가지 작업 코드를 확인하십시오. 대답은 ExecutorService (또는 2 개)과 하나 이상의 작업 대기열을 포함합니다. 이 방법에 대한

, 당신의 처리는 처리를 위해 중간 상태 정보와 함께,의 Runnable에 맞게 할 수 있어야합니다. 당신은 다음 단계를 수행하기 위해 두 번째의 Runnable를 추가하는 Runnable, 같은 ExecutorService에 각 단계를 먹이. 이렇게하면 실행 순서가 유지되지만 병렬로 원하는만큼 많은 스레드를 효과적으로 실행할 수 있습니다.

: 편집 : 당신이 명시 적으로 2 개 스레드 처리를 제한하려면 다른로서

제안했다은 Exchanger 라이브러리 클래스는이 사용될 수있다. 실행 순서를 유지하고 최신 4 코어 (및 8 코어) 시스템을 완벽하게 사용할 수 있기 때문에 위의 방법을 선호합니다. 또한 동기화를 약간 줄여야합니다.

0

T1 및 T2가 T1 해당 인쇄 단지 홀수 스레드 (1,3- 주도로 실행 가능한 인터페이스의 2 가지 구현이 경우 ,. ..)와 T2 번호 (1,2 .....에도 출력되는 한), 이것은() 공유 모니터 방법을 대기()를 사용하여 통지 할 수있다. 중요한 것은 각 스레드가 값을 인쇄하기 전에 공유 플래그를 확인하는 것입니다. 아래 코드가 작동합니다.

//The shared monitor 
public class Mutex { 
public static boolean oddFlag; 

} 

//The Thread that is supposed to print Odd numbers (assuming an upper limit of 99) 
public class OddPrinter implements Runnable { 
private Mutex mutex; 

public OddPrinter(Mutex mutex) { 
    this.mutex = mutex; 
} 

public synchronized void run() { 
    System.out.println("Started Thread: OddPrinter"); 
    int i; 
    for(i=1; i<100; i+=2) { 
     synchronized (mutex) { 
      while(!Mutex.oddFlag) { 
       try { 
        mutex.wait(); 
       } catch (InterruptedException ie) { 
        Thread.currentThread().interrupted(); 
       } 
      } 

      if(Mutex.oddFlag == true) { 
       System.out.println("Print from OddPrinter: "+i); 
       Mutex.oddFlag = false; 
       mutex.notify(); 
      } 


     } 
    } 
    System.out.println("Finished Thread: OddPrinter: "+i); 
} 

} 

//The Thread that is supposed to print Odd numbers (assuming an upper limit of 98) 
public class EvenPrinter implements Runnable { 
private Mutex mutex; 

public EvenPrinter(Mutex mutex) { 
    this.mutex = mutex; 
} 

public synchronized void run() { 
    System.out.println("Started Thread: EvenPrinter"); 
    int i; 
    for(i=2; i<100; i+=2) { 
     synchronized (mutex) { 
      while(Mutex.oddFlag) { 
       try { 
        mutex.wait(); 
       } catch (InterruptedException ie) { 
        Thread.currentThread().interrupted(); 
       } 
      } 

      if(!(Mutex.oddFlag == true)) { 
       System.out.println("Print from EvenPrinter: "+i); 
       Mutex.oddFlag = true; 
       mutex.notify(); 
      } 

     } 
    } 
    System.out.println("Finished Thread: EvenPrinter: "+i); 
} 

} 

//The test harness that executes the threads 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class NumberPrinterTest { 

public static void main(String[] args) throws Exception{ 
    ExecutorService es = Executors.newFixedThreadPool(2); 

    Mutex mutex = new Mutex(); 
    OddPrinter op = new OddPrinter(mutex); 
    EvenPrinter ep = new EvenPrinter(mutex); 
    Mutex.oddFlag = true; 
    es.execute(op); 
    es.execute(ep); 

    if(null != es){ 
     es.shutdown(); 
     try { 
      es.awaitTermination(1, TimeUnit.MINUTES); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupted(); 
     } 
    } 

} 

}