Reputation: 3229
So I have this code here, that adds my "NamePrinter" runnable class as ExecutorService tasks. Everything works fine, but I'd like to get rid of that extra class. So I am asking is there a way to submit method to ExexutorService?
Here is the code that I currently have:
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();
}
But I'd like it to be something like this:
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);
}
Is this something that is possible to achieve?
Upvotes: 3
Views: 4331
Reputation: 608
In this specific case, I think you'll not be able to do exactly what you want, because the run
method of Runnable
interface doesn't take any arguments. However, you can use lambda expressions since Java 8. So you have few options now:
1 - Define the method on-the-fly
final String name = "whatever";
exServ.execute(() -> {
System.out.println(name);
});
2 - Define a static method and then use static method reference
public static void printName()
{
System.out.println(ClassNameX.name);
}
exServ.execute(ClassTest::printName);
3 - Create an instance of your NamePrinter class - which doesn't need to implement the Runnable
interface - to store the parameters and then use instance method reference.
NamePrinter np = new NamePrinter("testName");
exServ.execute(np::namePrint);
Upvotes: 2
Reputation: 3641
There are some options for this:
Using anonymous class
es.submit { new Runnable() {
public void run() {
//do your stuff here
}
});
Use languages which support closures like Scala. However the API must support this, which ExecutorService doesn't.
Wait for Java 8 which will introduce closures.
Upvotes: 0
Reputation: 1502536
The closest you can come as an anonymous inner class:
for (int i = 0; i < 10; i++) {
final int x = i;
futures.add(es.submit(new Runnable() {
@Override public void run() {
namePrint(x + "name");
}
}));
}
Upvotes: 5
Reputation: 340903
You are essentially asking: is Java supporting functions as first class citizens (sometimes it is refered as closures or lambdas) - no, you can't do this in Java. You can in Groovy, Scala, JavaScript, C#... but not in Java.
Your NamePrinter
class (probably implementing Runnable
or Callable
) is the closest you can get in Java and this is the Java way (or you can use anonymous inner class).
Upvotes: 3