2013-07-05 7 views
1

AJAX에서 비동기 적으로 요청을 제출한다고 가정합니다. reposne이 반환되면 콜백 함수를 실행합니다.다중 스레드 환경에서 Java 콜백 함수

Java 다중 스레드 환경에서 동일한 것을 구현하는 가장 좋은 방법은 무엇입니까? 즉 메인 스레드는 자식 스레드를 생성하고 작업을 제출 한 다음 자식 스레드가 콜백 함수를 반환하고 메인 스레드가 실행해야합니다.

이것이 가능합니까? 메인 스레드에서 wait()을 수행 할 수 있고 자식 스레드에서 notify()를 수행 할 수 있지만이 경우 메인 스레드는 자식 스레드가 완료 될 때까지 대기합니다. 그러나 메인 스레드가 작업을 계속 AJAX로는 ... 그게 내가

답변

1

당신은 당신이 기다리는 돌아올 Future의 방법을 사용해서 배경에 작업을 수행하기 위해 ExecutorService을 사용할 수 원하는 것입니다 그 결과. 예를 들면 다음과 같습니다.

class Main { 
    private static final ExecutorService es = Executors.newCachedThreadPool(); 

    public static void main(final String... args) throws Throwable { 
    List<Future<Integer>> results = new ArrayList<>(); 
    for (int i = 0; i < 10; i++) { 
     results.add(asyncSum(i, i*i)); 
    } 
    // here, in the main thread, you can do whatever you want 
    // while the calculations are performed in background threads 
    // ... 

    // after the main thread finishes what it was doing, it 
    // can process the futures 
    for (final Future<Integer> result : results) { 
     System.out.println(result.get()); 
    } 
    } 

    // this method launches a calculation on a worker thread and immediately 
    // returns a Future, which is a reference to the result of the calculation 
    // once it is completed 
    private static Future<Integer> asyncSum(final int a, final int b) { 
    return es.submit(new Callable<Integer>() { 
     @Override public Integer call() throws Exception { 
     return a + b; 
     } 
    }); 
    } 
} 

위 예제에서 주 스레드는 첫 번째 계산이 완료 될 때까지 차단 한 다음 인쇄합니다. 그런 다음 두 번째 계산이 완료 될 때까지, 다음 등

당신은 그들이 (지정되지 않은 순서대로) 제공되면 결과를 인쇄 할 경우에, 당신이 가진 대신 CompletionService을 사용하고, 수, 그것을 인쇄 차단 결과 목록 및 iterating에 대해서는 CompletionService 자체에서 .take() 메서드를 통해 미래를 얻거나 계산이 완료 될 때까지 차단하는 .poll()을 얻습니다. 계산이 완료되면 Future를 반환하고 그렇지 않으면 null을 반환합니다. 계산이 완료되지 않았습니다. 이렇게하면 주 스레드가 차단되지 않습니다.

다음 예제에서는 CompletionService을 사용합니다. 블록하지 않는 주 스레드를 보여주고 백그라운드 스레드를 사용하여 계산을 수행하고 결과를 사용할 수있게 처리합니다.

class Main { 
    public static void main(String[] args) throws Throwable { 
    final ExecutorService es = Executors.newCachedThreadPool(); 
    final CompletionService<Integer> cs = new ExecutorCompletionService<>(es); 

    submitSomeCalculations(cs); 

    while (true) { 
     doMainThreadWork(); 
     processFinishedCalculations(cs); 
    } 
    } 

    private static void submitSomeCalculations(final CompletionService<Integer> cs) { 
    for (int i = 0; i < 10; i++) { 
     submitAsyncSum(cs, i, i * i); 
    } 
    } 

    private static void submitAsyncSum(final CompletionService<Integer> cs, final int a, final int b) { 
    cs.submit(new Callable<Integer>() { 
     @Override public Integer call() throws Exception { 
     Thread.sleep(100 + (long) (Math.random() * 900)); 
     return a + b; 
     } 
    }); 
    } 

    private static void processFinishedCalculations(final CompletionService<Integer> cs) throws ExecutionException, InterruptedException { 
    while (true) { 
     final Future<Integer> result = cs.poll(); 
     if (result == null) { 
     System.out.println("> no finished results..."); 
     break; 
     } else { 
     System.out.println("> result available: " + result.get()); 
     } 
    } 
    } 

    static void doMainThreadWork() { 
    System.out.println("work from main thread..."); 
    } 
} 
관련 문제