19

Standard Runnable interface has only non-parametrized run() method. There is also Callable<V> interface with call() method returning result of generic type. I need to pass generic parameter, something like this:

interface MyRunnable<E> {
  public abstract void run(E reference);
}
Is there any standard interface for this purpose or I must declare that basic one by myself?
mschayna
  • 1,270
  • 2
  • 14
  • 32
  • If you came over this when working with an **anonymous inner** `Runnable` or `Callable` you cannot and do not need to use parameters. See [this question](http://stackoverflow.com/q/9273900/1503237) and [the answer](http://stackoverflow.com/a/9273927/1503237) how this can be done. – Matthias Ronge Aug 19 '15 at 07:24

6 Answers6

14

Typically you would implement Runnable or Callable as a class that supported a genertic input parameter; e.g.

public class MyRunnable<T> implements Runnable {
  private final T t;

  public MyRunnable(T t) {
    this.t = t;
  }

  public void run() {
    // Reference t.
  }
}
Adamski
  • 51,827
  • 12
  • 103
  • 150
  • 1
    Thanks to all three guys who answered my question, all with one same right answer. Should accept all three answers... :) – mschayna Nov 02 '09 at 09:47
  • Yes :) you are right. I should wait couple of hours for fading answering away. – mschayna Nov 03 '09 at 08:57
11

Java 8 includes the java.util.function.Consumer<T> interface with the single non-default method void accept(T t).

There are many other related interfaces in that package.

andrewdotn
  • 27,806
  • 6
  • 80
  • 110
9

There is also com.google.common.base.Function<F, T> from Google CollectionsGuava.

If you set the output type to ? or Void (and always have it return null) you can use it as an alternative to Runnable with an input parameter.

This has the advantage of being able to use Functions.compose to transform the input value, Iterables.transform to apply it to every element of a collection etc.

James Moore
  • 7,594
  • 5
  • 62
  • 83
finnw
  • 45,253
  • 22
  • 134
  • 212
4

Generally if you wanna pass a parameter into the run() method you will subclass Runnable with a constructor that takes a parameter.

For example, You wanna do this:

// code
Runnable r = new YourRunnable();
r.run(someParam);
//more code

You need to do this:

// code
Runnable r = new YourRunnable(someParam);
r.run();
//more code

You will implement YourRunnable similar to below:

public class YourRunnable implements Runnable {
    Some param;
    public YourRunnable(Some param){
        this.param = param;
    }
    public void run(){
        // do something with param
    }
}
jjnguy
  • 128,890
  • 51
  • 289
  • 321
0

I suggest defining an interface as done in the original question. Further, avoid weak typing by making the interface specific to what it is supposed to do, rather than a meaning-free interface like Runnable.

Tom Hawtin - tackline
  • 139,906
  • 30
  • 206
  • 293
-3

Runnable isn't meant to be called directly by client code like foo.run() which would run sequentially in the current thread.

From the Runnable API:

The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments called run.

This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread. Being active simply means that a thread has been started and has not yet been stopped.

In addition, Runnable provides the means for a class to be active while not subclassing Thread. A class that implements Runnable can run without subclassing Thread by instantiating a Thread instance and passing itself in as the target. In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.

Instead, you create a new Thread instance based on your runnable, and then call bar.start(). It is then the JVM's responsibility to call run() in this separate thread.

Example:

 public class Foo<E> implements Runnable {
     private final E e;
     public Foo(E e) { ... }
     @Override
     public void run() {
         do something with e.
     }
 }

 Foo<String> foo = new Foo("hello");
 Thread bar = new Thread(foo);
 bar.start();
toolkit
  • 47,529
  • 17
  • 103
  • 134
  • 6
    `Runnable` has many usages outside of explicit threading. The semantics of the interface is just "an object that represents a piece of work to be run at some time". – gustafc Nov 02 '09 at 09:45
  • 1
    Disagree with your comment. See the API for its intended use. – toolkit Nov 02 '09 at 10:15
  • 4
    I agree with gustaf. If multithreading were the only intended purpose of Runnable, it'd be defined in java.util.concurrent, not java.lang. But more importantly, your statement that "Runnable isn't meant to be called directly by client code" is incorrect - if that were the case, the docs wouldn't suggest an implementation of `run()` that instantiates a thread and passes itself in. In that use case, if you're not calling `run()` directly, and not relying on an Executor to handle the threading (the Runnable is handling threading itself), how does it ever run? Simple - just call `run()` – Dathan Jul 20 '11 at 23:42
  • @Dathan `Runnable` is not in `java.util.concurrent` because the former originated in Java 1 while the latter came several years later in Java 5. – Basil Bourque Dec 06 '20 at 22:36