2013-07-11 2 views
0

몇 가지 특정 시간마다 자주 업데이트해야하므로 java ExecutorService를 테스트하는 방법이 있지만 내 방법이 자주 업데이트되지 않는 이유를 알려주실 수 있습니까? ExecutorService가 자주 실행되지 않는 이유

내 수업 사전에

package com; 

import java.lang.reflect.Method; 
import java.util.concurrent.*; 

public class FutureTask { 
    private static ExecutorService executor = Executors.newCachedThreadPool(); 
    private static FutureTask _instance = new FutureTask(); 

    public static FutureTask getInstance() { 
     return _instance; 
    } 

    private static int timoutsec = 15; 

    public Object submiteTask(final Object obj, final Method method, 
      final Object[] params) throws Exception { 
     return submiteTask(obj, method, params, -1); 
    } 

    public Object submiteTask(final Object obj, final Method method, 
      final Object[] params, int timeoutSeconds) throws Exception { 
     if (null != obj && method != null) { 
      Callable<Object> task = new Callable<Object>() { 
       public Object call() { 
        try { 
         method.setAccessible(true); 
         Object resultObj = method.invoke(obj, params); 
         return resultObj; 
        } catch (Exception e) { 
        } 
        return null; 
       } 
      }; 
      Future<Object> future = executor.submit(task); 
      try { 
       Object result = null; 
       if (timeoutSeconds < 0) { 
        result = future.get(timoutsec, TimeUnit.SECONDS); 
       } else { 
        result = future.get(timeoutSeconds, TimeUnit.SECONDS); 
       } 
       return result; 
      } catch (TimeoutException e) { 
      } catch (Exception e) { 
      } finally { 
       future.cancel(true); 
      } 
     } 
     return null; 
    } 

    public static void main(String args[]) { 
     try { 
      FutureTask.getInstance().submiteTask(
        new TestingFutureTaskUtil(), 
        TestingFutureTaskUtil.class.getDeclaredMethod(
          "updateMethodCalled", 
          new Class<?>[] { String.class }), 
        new Object[] { "UBSC!OC1010" }, 1); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

TestingFutureTaskUtil.java

package com; 

public class TestingFutureTaskUtil { 

    public void updateMethodCalled(String symbol) { 

     System.out.println("updateMethodCalled" + symbol); 

    } 

} 

감사

FutureTask.java 있습니다.

+0

그게 당신의 문제를 해결할 수 없지만 당신의'FutureTask' 클래스의 이름을 다른 것으로 바꿀 것을 제안합니다. 이것은 이미 java.util.concurrent 패키지에있는 클래스의 이름입니다. – assylias

+1

이 코드는 작성된대로 이해가되지 않습니다. 일반적으로 별도의 스레드에서 작업 실행을 처리하려는 경우에는'ExecutorService'를 사용합니다. 이 경우 ExecutorService에 작업을 추가하지만 완료 될 때까지 주 스레드를 차단합니다. 확실히 그게 네가하려는 일이 아니야? 이것은 실행자 –

+0

@ColinMorelli의 목적을 완전히 무마하고, 당신의 의견에 동의합니다. 제 프로덕션 코드에서 언급 한 그대로입니다. 그러나 시나리오를 표현하기 위해 간단한 독립 실행 형 프로그램을 사용하여 샘플을 복제했습니다. – Kiran

답변

1

정상적인 ExecutorService를 사용 중입니다. 작업을 예약 할 수 없습니다. ScheduledExecutorService를 사용해야합니다.

는 다음과 같은 변경해야

private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(poolSize); 

과 :

Future<Object> future = executor.scheduleAtFixedRate(task, timeoutSeconds, timeoutSeconds, TimeUnit.SECONDS); 

이제 작업이 실행됩니다 모든 "timeoutSeconds"(초). 그런 다음 ScheduledFuture를 반환하고 업데이트 된 값을 가져올 수 있습니다.

어쩌면 그것은 단지 예제 때문일 수 있습니다. 그러나 나는 호출 할 수있는 외부를 만들고 FutureTask에 건네줍니다. 당신은 반사가 필요하지 않습니다. 또한 호출 스레드가 항상 계산이 완료 될 때까지 기다리기 때문에 비동기 호출을 수행하는 방식이 잘못되었습니다. 따라서 다른 스레드에서 메서드를 실행해도 아무런 이점도 얻지 못합니다. 어쩌면 당신이하고있는 일의 전체적인 디자인을 다시 생각할 필요가있을 것입니다.

1

하나의 작업 만 제출하므로 updateMethodCalled는 한 번만 호출됩니다.

+0

@Kiran 특정 간격으로이 메소드를 실행하려는 경우 java.util.Timer를 원한다고 생각합니다. –

+0

이 목적으로 java.util.Timer 클래스를 사용하지 마십시오. 각각의 타이머는 별도의 스레드로 실행되며, 99,99 %의 시간을 전혀 소비하지 않는 수 백/수천 개의 스레드로 끝날 수 있습니다. 물론 응용 프로그램에 따라 다릅니다. – ssindelar

관련 문제