How can I pass a parameter to a Java Thread?

Viewed 424653

Can anyone suggest to me how I can pass a parameter to a thread?

Also, how does it work for anonymous classes?

19 Answers

You need to pass the parameter in the constructor to the Runnable object:

public class MyRunnable implements Runnable {

   public MyRunnable(Object parameter) {
       // store parameter for later user
   }

   public void run() {
   }
}

and invoke it thus:

Runnable r = new MyRunnable(param_value);
new Thread(r).start();

For Anonymous classes:

In response to question edits here is how it works for Anonymous classes

   final X parameter = ...; // the final is important
   Thread t = new Thread(new Runnable() {
       p = parameter;
       public void run() { 
         ...
       };
   t.start();

Named classes:

You have a class that extends Thread (or implements Runnable) and a constructor with the parameters you'd like to pass. Then, when you create the new thread, you have to pass in the arguments, and then start the thread, something like this:

Thread t = new MyThread(args...);
t.start();

Runnable is a much better solution than Thread BTW. So I'd prefer:

   public class MyRunnable implements Runnable {
      private X parameter;
      public MyRunnable(X parameter) {
         this.parameter = parameter;
      }

      public void run() {
      }
   }
   Thread t = new Thread(new MyRunnable(parameter));
   t.start();

This answer is basically the same as this similar question: How to pass parameters to a Thread object

via constructor of a Runnable or Thread class

class MyThread extends Thread {

    private String to;

    public MyThread(String to) {
        this.to = to;
    }

    @Override
    public void run() {
        System.out.println("hello " + to);
    }
}

public static void main(String[] args) {
    new MyThread("world!").start();
}

When you create a thread, you need an instance of Runnable. The easiest way to pass in a parameter would be to pass it in as an argument to the constructor:

public class MyRunnable implements Runnable {

    private volatile String myParam;

    public MyRunnable(String myParam){
        this.myParam = myParam;
        ...
    }

    public void run(){
        // do something with myParam here
        ...
    }

}

MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();

If you then want to change the parameter while the thread is running, you can simply add a setter method to your runnable class:

public void setMyParam(String value){
    this.myParam = value;
}

Once you have this, you can change the value of the parameter by calling like this:

myRunnable.setMyParam("Goodbye World");

Of course, if you want to trigger an action when the parameter is changed, you will have to use locks, which makes things considerably more complex.

I know that I'm a few years late, but I came across this issue and took an unorthodox approach. I wanted to do it without making a new class, so this is what I came up with:

int x = 0;
new Thread((new Runnable() {
     int x;
     public void run() {
        // stuff with x and whatever else you want
     }
     public Runnable pass(int x) {
           this.x = x;
           return this;
     }
}).pass(x)).start();

You can either extend the Thread class or the Runnable class and provide parameters as you want. There are simple examples in the docs. I'll port them here:

 class PrimeThread extends Thread {
     long minPrime;
     PrimeThread(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }

 PrimeThread p = new PrimeThread(143);
 p.start();

 class PrimeRun implements Runnable {
     long minPrime;
     PrimeRun(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }


 PrimeRun p = new PrimeRun(143);
 new Thread(p).start();

To create a thread you normally create your own implementation of Runnable. Pass the parameters to the thread in the constructor of this class.

class MyThread implements Runnable{
   private int a;
   private String b;
   private double c;

   public MyThread(int a, String b, double c){
      this.a = a;
      this.b = b;
      this.c = c;
   }

   public void run(){
      doSomething(a, b, c);
   }
}

Either write a class that implements Runnable, and pass whatever you need in a suitably defined constructor, or write a class that extends Thread with a suitably defined constructor that calls super() with appropriate parameters.

Parameter passing via the start() and run() methods:

// Tester
public static void main(String... args) throws Exception {
    ThreadType2 t = new ThreadType2(new RunnableType2(){
        public void run(Object object) {
            System.out.println("Parameter="+object);
        }});
    t.start("the parameter");
}

// New class 1 of 2
public class ThreadType2 {
    final private Thread thread;
    private Object objectIn = null;
    ThreadType2(final RunnableType2 runnableType2) {
        thread = new Thread(new Runnable() {
            public void run() {
                runnableType2.run(objectIn);
            }});
    }
    public void start(final Object object) {
        this.objectIn = object;
        thread.start();
    }
    // If you want to do things like setDaemon(true); 
    public Thread getThread() {
        return thread;
    }
}

// New class 2 of 2
public interface RunnableType2 {
    public void run(Object object);
}

You can derive a class from Runnable, and during the construction (say) pass the parameter in.

Then launch it using Thread.start(Runnable r);

If you mean whilst the thread is running, then simply hold a reference to your derived object in the calling thread, and call the appropriate setter methods (synchronising where appropriate)

Create a local variable in your class that extends Thread or implements Runnable.

public class Extractor extends Thread {
    public String webpage = "";
    public Extractor(String w){
        webpage = w;
    }
    public void setWebpage(String l){
        webpage = l;
    }

    @Override
    public void run() {// l is link
        System.out.println(webpage);
    }
    public String toString(){
        return "Page: "+webpage;
    }}

This way, you can pass a variable when you run it.

Extractor e = new Extractor("www.google.com");
e.start();

The output:

"www.google.com"

First I want to point out that other answers are true. However, using the parameter in the constructor may not be the best idea for all of you.

In many scenarios you will want to use "Anonymous Inner Class", and override the run() method, because defining specific class for every use is painful. (new MyRunnable(){...})

And at the time you create that Runnable, the parameter may not be available to you to pass it in the constructor. If for example, you pass this object to a method, that will perform some work in separate thread and then call your runnable, applying the result from that work to it.

In that case, using a method like this one: public MyRunnable withParameter(Object parameter), may turn out to be far more useful choice.

I do not claim that this is the best solution to the problem, but it will get the job done.

Related