2012-09-25 2 views
0

내 클래스에서 일부 비동기 처리 및 상위 클래스의 값 설정을 수행하는 내부 클래스가 있습니다. 예 : 나는이 문제를 어떻게합니까간단한 멀티 스레딩 java

class Runner{ 
    public static void main(String[] args){ 
     Myclass instance = new Myclass(); 

     //This is always null because runner class doesn't wait for Inner class to 
     //complete asynchronous processing and to set test value 
     System.out.println(instance.getTestValueFromMyClass()); 
    } 
} 

:

class Myclass{ 
    String test; 

    public getTestValueFromMyClass(){ 
     //this starts asynchronous processing on my inner class 
    } 

    //inner class 
    class InnerClass extends TimerTask{ 
     //doing something asynchronously, when this process is done 
     test = "somevalue"; 
    } 
} 

여기에서 지금은 러너 클래스의 문제인가?

+3

아무 것도 동시에 수행하지 않는 것처럼 보이므로 하나의 스레드 만 사용하게됩니다. 비동기 작업을 기다리고 싶다면 ExecutorService와 Future.get()을 사용하는 것이 좋습니다. –

+0

컴파일 할 것 같지 않습니다. –

+0

예 비동기 작업이 완료 될 때까지 기다렸다가 그 결과를 출력하려고했지만, 어떻게하면 –

답변

2

다른 사람들도 비슷한 아이디어를 제안했지만 다른 하나는 Callable 인 스레드 풀을 사용합니다.

비동기 처리를 수행중인 클래스는 계산 된 값을 반환하는 Callable을 구현해야합니다. 이 예에서는 String을 반환하지만 자세한 정보가 포함 된 자신의 개체를 반환 할 수도 있습니다.

public class MyClass implements Callable<String> { 
    public String call() { 
     //doing something asynchronously, when this process is done 
     return "somevalue"; 
    } 
} 

귀하의 Runner 클래스는 다음 스레드 풀을 만들 백그라운드에서 비동기 작업을 해고하고,이 끝날 때까지 나중에 기다릴 것입니다. 스레드 풀에 Callable 작업을 제출하면 Future 클래스 백이 생성되어 비동기 작업이 완료 될 때까지 기다리고 반환 값을 가져올 수 있습니다.

public class Runner{ 
    public static void main(String[] args) { 
     // you can use newFixedThreadPool(...) if you need to submit multiple 
     ExecutorService threadPool = Executors.newSingleThreadExecutor(); 
     // you could store this future in a collection if you have multiple 
     Future<String> future = threadPool.submit(new MyClass()); 
     // after submitting the final job, we _must_ shutdown the pool 
     threadPool.shutdown(); 

     // do other stuff in the "foreground" while MyClass runs in the background 

     // wait for the background task to complete and gets its return value 
     // this can throw an exception if the call() method threw 
     String value = future.get(); 
     System.out.println(value); 
    } 
} 
0

처리가 완료되면 처리기를 사용하여 메시지를 게시 할 수 있습니다!

+0

답장을 보내 주셔서 감사합니다. 예/링크가 있습니까? 비슷한 내용을 말하고 있습니다. –

+0

에 대한 이야기는 아직 미정입니다. 안드로이드 개발을위한 제안이었습니다. 스레드를 필요로하지 않습니다. 그러나 별도의 스레드가 있어야한다고 주장하는 경우 처리가 준비되면 메소드를 호출하십시오! –

0
class Myclass{ 
    // pre initialize thread pool 
    private static ExecutorService executor = Executors.newFixedThreadPool(5); 

    private String test; 

    public String getTestValueFromMyClass() throws Exception { 
     // start asynchronous calculations 
     Future<String> resultHandler = 
      executor.submit(new Callable<String>() { 
        @Override 
        public String call() throws Exception { 
         return "Asynchronously calculated result"; 
        } 
       }); 
     // do something in current thread 
     // ... 
     // wait until asynchronous task ends, get result 
     // and assign it to instance variable 
     this.test = resultHandler.get(); 

     return test; // returns string "Asynchronously calculated result" 
    } 
} 
+0

이것은 문자열을 반환합니다. 비동기식으로 계산 된 결과이지만 내 프로그램이 여전히 실행 중입니다. 왜 끝나지 않습니까? –

+0

'resultHandler.get()'은 계산이 완료 될 때까지 기다렸다가 결과를 검색하기 때문에 (timeout을 가진'get'의 버전도 있습니다) : http://docs.oracle.com/javase/1.5.0 /docs/api/java/util/concurrent/Future.html#get%28%29 – stemm

2

분명히, 당신은 InnerClass 실행을 기다리는 getTestValueFromMyClass을해야한다. 동기화 기능 (Semaphore, CountdownLatch, BlockingQueue ...)을 통해 수행 할 수 있습니다. 하지만 가장 쉬운 방법은 java.util.Timer 대신 java.util.concurrent.ScheduledThreadPoolExecutor을 사용하는 것입니다. 메서드 schedule(Callable<V> callable, long delay, TimeUnit unit)은 Future를 반환하고 Future.get()은 기다린 다음 계산 된 값을 반환합니다.

2

하나의 매우 간단한 메커니즘은 BlockingQueue을 사용하여 스레드간에 통신하는 것입니다. 여기 스레드 클래스에서 대기열을 만들지 만 호출자에서 쉽게 생성하여 스레드에 전달할 수 있습니다.

public class Runner { 
    static class MyClass implements Runnable { 
    // Thread will post to this queue when it completes. 
    BlockingQueue q = new ArrayBlockingQueue(1); 

    // Call to wait for the post. 
    public void waitForFinish() throws InterruptedException { 
     // Just take! This will wait until something gets posted. 
     q.take(); 
    } 

    @Override 
    public void run() { 
     try { 
     // Just wait ten seconds. 
     Thread.sleep(10000); 
     } catch (InterruptedException ex) { 
     // Just exit when interrupted. 
     } finally { 
     try { 
      // Signal finished. 
      q.put("Done"); 
     } catch (InterruptedException ex) { 
      // Just exit when interrupted. 
     } 
     } 
    } 
    } 

    public static void main(String[] args) throws InterruptedException { 
    // Make my instance. 
    MyClass instance = new MyClass(); 
    // Fire it off. 
    new Thread(instance).start(); 
    // Wait for it to finish. 
    instance.waitForFinish(); 
    // All done. 
    System.out.println("Finished"); 
    } 
}