How can I pass a parameter to a Java Thread?

JavaMultithreading

Java Problem Overview


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

Also, how does it work for anonymous classes?

Java Solutions


Solution 1 - Java

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

Solution 2 - Java

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

Solution 3 - Java

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

Solution 4 - Java

This answer comes very late, but maybe someone will find it useful. It is about how to pass a parameter(s) to a Runnable without even declaring named class (handy for inliners):

    String someValue = "Just a demo, really...";

    new Thread(new Runnable() {
        private String myParam;

        public Runnable init(String myParam) {
            this.myParam = myParam;
            return this;
        }

        @Override
        public void run() {
            System.out.println("This is called from another thread.");
            System.out.println(this.myParam);
        }
    }.init(someValue)).start();

Of course you can postpone execution of start to some more convenient or appropriate moment. And it is up to you what will be the signature of init method (so it may take more and/or different arguments) and of course even its name, but basically you get an idea.

In fact there is also another way of passing a parameter to an anonymous class, with the use of the initializer blocks. Consider this:

    String someValue = "Another demo, no serious thing...";
    int anotherValue = 42;

    new Thread(new Runnable() {
        private String myParam;
        private int myOtherParam;
        // instance initializer
        {
            this.myParam = someValue;
            this.myOtherParam = anotherValue;
        }

        @Override
        public void run() {
            System.out.println("This comes from another thread.");
            System.out.println(this.myParam + ", " + this.myOtherParam);
        }
    }).start();

So all happens inside of the initializer block.

Solution 5 - Java

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.

Solution 6 - Java

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

Solution 7 - Java

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

Solution 8 - Java

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

Solution 9 - Java

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.

Solution 10 - Java

In Java 8 you can use lambda expressions with the Concurrency API & the ExecutorService as a higher level replacement for working with threads directly:

> newCachedThreadPool() Creates a thread pool that creates new threads > as needed, but will reuse previously constructed threads when they are > available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks.

	private static final ExecutorService executor = Executors.newCachedThreadPool();

	executor.submit(() -> {
		myFunction(myParam1, myParam2);
	});

See also executors javadocs.

Solution 11 - Java

As of Java 8, you can use a lambda to capture parameters that are effectively final. For example:

final String param1 = "First param";
final int param2 = 2;
new Thread(() -> {
    // Do whatever you want here: param1 and param2 are in-scope!
    System.out.println(param1);
    System.out.println(param2);
}).start();

Solution 12 - Java

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

Solution 13 - Java

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)

Solution 14 - Java

There is a simple way of passing parameters into runnables. Code:

public void Function(final type variable) {
    Runnable runnable = new Runnable() {
        public void run() {
            //Code adding here...
        }
    };
    new Thread(runnable).start();
}

Solution 15 - Java

No you can't pass parameters to the run() method. The signature tells you that (it has no parameters). Probably the easiest way to do this would be to use a purpose-built object that takes a parameter in the constructor and stores it in a final variable:

public class WorkingTask implements Runnable
{
    private final Object toWorkWith;
 
    public WorkingTask(Object workOnMe)
    {
        toWorkWith = workOnMe;
    }
 
    public void run()
    {
        //do work
    }
}
 
//...
Thread t = new Thread(new WorkingTask(theData));
t.start();

Once you do that - you have to be careful of the data integrity of the object you pass into the 'WorkingTask'. The data will now exist in two different threads so you have to make sure it is Thread Safe.

Solution 16 - Java

One further option; this approach lets you use the Runnable item like an asynchronous function call. If your task does not need to return a result, e.g. it just performs some action you don't need to worry about how you pass back an "outcome".

This pattern lets you reuse an item, where you need some kind of internal state. When not passing parameter(s) in the constructor care is needed to mediate the programs access to parameters. You may need more checks if your use-case involves different callers, etc.

public class MyRunnable implements Runnable 
{
  private final Boolean PARAMETER_LOCK  = false;
  private X parameter;

  public MyRunnable(X parameter) {
     this.parameter = parameter;
  }

  public void setParameter( final X newParameter ){

      boolean done = false;
      synchronize( PARAMETER_LOCK )
      {
          if( null == parameter )
          {
              parameter = newParameter;
              done = true;
          }
      }
      if( ! done )
      {
          throw new RuntimeException("MyRunnable - Parameter not cleared." );
      }
  }


  public void clearParameter(){

      synchronize( PARAMETER_LOCK )
      {
          parameter = null;
      }
  }


  public void run() {

      X localParameter;

      synchronize( PARAMETER_LOCK )
      {
          localParameter = parameter;
      }

      if( null != localParameter )
      {
         clearParameter();   //-- could clear now, or later, or not at all ...
         doSomeStuff( localParameter );
      }

  }

}

Thread t = new Thread(new MyRunnable(parameter)); t.start();

If you need a result of processing, you will also need to coordinate completion of MyRunnable when the sub-task finishes. You could pass a call back or just wait on the Thread 't', etc.

Solution 17 - Java

Specially for Android

For callback purposes I usually implement my own generic Runnable with input parameter(s):

public interface Runnable<TResult> {
    void run(TResult result);
}

Usage is simple:

myManager.doCallbackOperation(new Runnable<MyResult>() {
	@Override
	public void run(MyResult result) {
		// do something with the result
	}
});

In manager:

public void doCallbackOperation(Runnable<MyResult> runnable) {
	new AsyncTask<Void, Void, MyResult>() {
		@Override
		protected MyResult doInBackground(Void... params) {
			// do background operation
			return new MyResult(); // return resulting object
		}

		@Override
		protected void onPostExecute(MyResult result) {
			// execute runnable passing the result when operation has finished
			runnable.run(result);
		}
	}.execute();
}

Solution 18 - Java

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"

Solution 19 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteveView Question on Stackoverflow
Solution 1 - JavaAlnitakView Answer on Stackoverflow
Solution 2 - JavaNick FortescueView Answer on Stackoverflow
Solution 3 - JavadfaView Answer on Stackoverflow
Solution 4 - JavaCromaxView Answer on Stackoverflow
Solution 5 - JavajwoolardView Answer on Stackoverflow
Solution 6 - JavameyiView Answer on Stackoverflow
Solution 7 - Javabruno condeView Answer on Stackoverflow
Solution 8 - JavaMnementhView Answer on Stackoverflow
Solution 9 - JavaPaulJWilliamsView Answer on Stackoverflow
Solution 10 - JavaStuart CardallView Answer on Stackoverflow
Solution 11 - JavaJeff GView Answer on Stackoverflow
Solution 12 - JavaJava42View Answer on Stackoverflow
Solution 13 - JavaBrian AgnewView Answer on Stackoverflow
Solution 14 - JavaChromiumView Answer on Stackoverflow
Solution 15 - JavaMihir PatelView Answer on Stackoverflow
Solution 16 - JavawillView Answer on Stackoverflow
Solution 17 - JavaAndreiView Answer on Stackoverflow
Solution 18 - JavaCalvin KView Answer on Stackoverflow
Solution 19 - JavaH.A.H.View Answer on Stackoverflow