2013-07-11 3 views
0

Существует метод, который мне нужно обновлять часто для каждого определенного времени, поэтому я тестировал Java ExecutorService, но мой метод часто не обновляется, не могли бы вы рассказать мне, почему?почему ExecutorService не часто выполняется.

Это мои классы

FutureTask.java

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); 

    } 

} 

Спасибо заранее.

+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. Чем вам не нужно Reflection. Также, как вы выполняете асинхронный вызов, неправильно, потому что вызывающий поток всегда ожидает завершения вычисления. Таким образом, вы не получаете никаких преимуществ от запуска метода в другом потоке. Возможно, вам нужно переосмыслить весь дизайн того, что вы делаете.

1

Вы отправляете только одно задание, поэтому updateMethodCalled вызывается только один раз.

+0

@Kiran Я думаю, вам нужен 'java.util.Timer', если вы пытаетесь запустить этот метод на определенном интервале –

+0

Не используйте для этого класс java.util.Timer. Каждый таймер запускается в отдельном потоке, и вы можете получить сотни/тысячи потоков, которые ничего не делают в 99,99% случаев. Зависит от применения курса. – ssindelar

Смежные вопросы