2014-12-26 12 views
0

wait(), notify(), notifyAll(), Thread.run(), synhronized 등과 같은 원시 자바 동시 구조를 사용하는 프로젝트에서 작업 중입니다. 내 프로젝트에는 큐로부터 오브젝트를 주기적으로 취득하는 복수의 thread (Thread 클래스의 확장 기능) 따라서 TimerTask 클래스가있는 Timer 클래스를 사용합니다.주기적으로 여러 스레드에 알리기

내 문제는 다른 스레드를 주기적으로 깨우는 방법을 얻을 수 없다는 것입니다. 내 메인 클래스는 이러한 스레드 또는 타이머 클래스가 아닙니다. 따라서 나는 다른 클래스에서 그들의 실행을 호출합니다. 이 스레드를 대기시키고 100 밀리 초당 한 번만 알리는 방법을 알아낼 수 없었습니다.

public class Controller extends Timer{ 

    int counter; 
    TimerTask task; 
    final Controller c = this; 

    public class PeriodicTime extends TimerTask { 

     @Override 
     public void run() { 

      if(counter > 0) { 
       //do some stuff to wake up threads 

      } 
      counter++; 
     } 
    } 

    Controller() { 
     super(); 
     this.task = new PeriodicTime(); 
     counter = 0; 
     this.schedule(task, 300, 100); 
    } 
} 

그리고 내 스레드 클래스는 다음과 같습니다 : 내 타이머 클래스는 지금

public class Element extends Thread { 


    public void run() { 

     // do something to get an object from another class (a queue) 
    } 
} 

, 내가 스레드 클래스에 출시 정기적으로 확인하는 방법을 정말 혼란 스러워요. 나는 wait()/notify()를 사용할 지 여부를 알 수 없었다.

앞서 말했듯이, 나는 여러 개의 Element 클래스를 생성 할 것이다. 그들은 동기화 작업을합니다. 그렇다면 어떻게해야합니까?

+0

나는 당신이 선택의 여지가 있다면 당신이 정말로 그것을 이런 식으로하지 않을 것 같은이, 숙제입니다 가정합니다. ExecutorService는 훨씬 단순하게 원하는 것을 수행합니다. –

+0

대기/알림을 수행하려면 다른 개체가 알림을 보내는 동안 기다리는 공통 개체에 액세스해야합니다. 당신은'대기열'을 어떻게 언급 했습니까? –

+0

예 숙제이므로 수행 방법을 선택할 수 없습니다. 내 대기열에는 작업이 동기화 된 "put"및 "get"메소드가 있습니다. 개체 수에 따라 이러한 메서드에 "wait"및 "notify"를 넣습니다. – anyName

답변

0

뮤텍스를 나타내는 개체의 목록을 만듭니다. 각 요소 스레드는 목록에서 하나의 뮤텍스를 가져오고 타이머 작업은 목록을 가져옵니다.

TimerTask는 기간이 만료되면 모든 mutex 객체에 대해 notify()를 호출합니다. 이렇게하면 요소 스레드가 깨어납니다.

요소 스레드는 큐의 데이터를 처리하고 완료되면 각 스레드는 해당 뮤텍스 개체에서 wait()를 호출합니다.

여러 소비자가 있기 때문에 대기열에 스레드 안전성이 필요하지만 TimerTask가 처리하므로 차단 논리가 필요하지 않습니다.

또한 내가 올바르게 이해한다면, 엘리먼트가 데이터를 처리 할 때 대기열에 다시 넣기를 원할 것입니다. 이를 위해 요소가 완료된 후 첫 번째 요소로 배수 할 수있는 보조 대기열을 사용할 수 있습니다 (이 작업은 TimerTask에 의해 수행되며 Element가 이동할 때 요소가 깨어나고 감소 할 때 증가하는 원자 계수기가 필요함) 자다). 또는 요소를 깨우기 직전에 대기열에 넣을 수있는 "중지"값을 사용할 수 있으며 도달 할 때까지 작동하게 할 수 있습니다. N 요소 스레드의 경우 N 중지 값을 넣어야 모든 메시지를받을 수 있습니다. 사용 방법

뮤텍스는 :

List<Object> mutexList; 
//initialize the list with plain Objects. You just need them to be separate instances. 
.... 
//When creating Element threads add one object from the list to each Element. 
.... 
//in Element code 
public class Element extends Thread { 
    //This is one element from the list 
    private Object mutex; 


    public void run() { 
     // do something to get an object from another class (a queue) 
     //.... 
     synchronized(mutex){ 
      mutex.wait(); 
     } 
    } 
} 
// in timerTask code 
public class PeriodicTime extends TimerTask { 

    List<Object> mutexList; 

    @Override 
    public void run() { 

     if(counter > 0) { 
      //do some stuff to wake up threads 
      for(Object mutex:mutexList){ 
       mutex.notify(); 
      } 
     } 
     counter++; 
    } 
} 
+0

답변 해 주셔서 감사합니다. 아니요, 요소는 데이터를 다시 저장하지 않습니다. 새로운 데이터를 누군가가 인수 할 때마다 대기열에 넣는 "소유자"클래스가 있습니다. 내가 틀렸어도 퍼팅 프로세스가 정확하게 작동하고주기적인 일이 필요하지 않습니다. 하지만 여전히 뮤텍스 개체를 사용하는 방법을 잘 모르겠습니다. 이 간단한 코드 예제를 제공 할 수 있습니까? 고마워. – anyName

+0

뮤텍스를 사용하는 간단한 예제를 추가했습니다. 그러나이 설정이 원하지 않는 동작을 생성 할 수있는 경우가 있기 때문에 사용자의 요구에 따라이를 향상시킬 수도 있지만이 답변의 범위를 벗어납니다. – miljanm

+0

자세한 답변 해 주셔서 감사합니다. 하지만 여전히 한 번만 작동합니다. 왜 그런지 모르겠습니다. 어쨌든, 다시 한번 감사드립니다. 어떤 방식 으로든 해결하도록하겠습니다. – anyName