2012-07-24 3 views
3

Итак, у меня есть этот код, который добавляет мой исполняемый класс «NamePrinter» как задачи ExecutorService. Все работает нормально, но я бы хотел избавиться от этого дополнительного класса. Поэтому я спрашиваю, есть ли способ отправить метод ExexutorService?Метод отправки в ExecutorService Java

Вот код, который я в настоящее время есть:

public void start(){ 
     Collection<Future<?>> futures = new LinkedList<>(); 
     final ExecutorService es = Executors.newFixedThreadPool(poolSize); 

     for (int i = 0; i < 10; i++) { 
     futures.add(es.submit(new NamePrinter(name))); 
     } 

     es.shutdown(); 
} 

Но я хотел бы, чтобы это было что-то вроде этого:

public void start(){ 
      Collection<Future<?>> futures = new LinkedList<>(); 
      final ExecutorService es = Executors.newFixedThreadPool(poolSize); 

      for (int i = 0; i < 10; i++) { 
      futures.add(es.submit(namePrint(i+"name"))); // This code doesn't work, I just made it so you could understand what I mean. 
      } 

      es.shutdown(); 
    } 

public void namePrint(String name){ // I'd like this to be the task that ExecutorService runs. 

System.out.println(name); 

} 

Является ли это то, что можно достичь?

ответ

5

Ближайший вы можете прийти как анонимный внутренний класс:

for (int i = 0; i < 10; i++) { 
    final int x = i; 
    futures.add(es.submit(new Runnable() { 
     @Override public void run() { 
      namePrint(x + "name"); 
     } 
    })); 
} 
+0

ОК, так что это либо этот, либо другой класс? –

+0

Это еще один класс Runnable. Это похоже на синтаксический сахар над вашим исходным кодом. –

+0

Могу ли я использовать мои общедоступные переменные класса из этого анонимного внутреннего класса? –

3

Вы по существу вопроса: является Java поддерживает функцию как граждане первого класса (иногда это refered, как закрытие или Лямбд) - нет, вы не можете сделать это в Java. Вы можете использовать Groovy, Scala, JavaScript, C# ... но не в Java.

Вашего NamePrinter класс (возможно осуществление Runnable или Callable) является ближайшим вы можете получить в Java, и это путь Java (или вы можете использовать анонимный внутренний класс).

+0

То есть вы не можете сделать это в Java * до тех пор, пока Java 8 не добавит поддержку закрытий. –

+0

@ AndyThomas-Cramer: хорошо, мы будем жить достаточно долго ;-) –

+0

Нам удалось сделать это до тех пор, пока не будут добавлены дженерики. :) –

0

Есть несколько вариантов для этого:

  1. Использование анонимного класса

    es.submit { new Runnable() { 
    public void run() { 
        //do your stuff here 
    } 
    }); 
    
  2. Используйте языки, которые опорные затворы, такие как Scala. Однако API должен поддерживать это, чего нет у ExecutorService.

  3. Ждут Java 8, который представит закрытие.

1

В данном конкретном случае, я думаю, вы не будете в состоянии сделать точно то, что вы хотите, потому что run метод Runnable интерфейса не принимает никаких аргументов. Тем не менее, вы можете использовать лямбда-выражения с Java 8. Таким образом, у вас есть несколько вариантов в настоящее время:

1 - Определение метода на лету

final String name = "whatever"; 

exServ.execute(() -> {    
    System.out.println(name); 
}); 

2 - Определить статический метод и затем использовать статический эталонный метод

public static void printName() 
{ 
    System.out.println(ClassNameX.name); 
} 

exServ.execute(ClassTest::printName); 

3 - Создать экземпляр вашего класса NamePrinter, который не нуждается в реализации интерфейса Runnable - чтобы сохранить параметры, а затем использовать ссылку метода экземпляра.

NamePrinter np = new NamePrinter("testName"); 

exServ.execute(np::namePrint); 
Смежные вопросы