How to pass an argument to a thread [duplicate] - java

This question already has answers here:
How can I pass a parameter to a Java Thread?
(19 answers)
Closed 9 years ago.
Assume I would like to pass the following variable
String foo = "hello world";
as an argument to the following thread
new Thread(new Runnable() {
#Override
public void run() {
// SOME CODE HERE REQUIRES VARIABLE
}
}).start();
Can someone please explain how to do this.
Thanks.

Subclass Thread:
public class MyThread extends Thread {
private String arg;
public MyThread(String arg) {
this.arg = arg;
}
#Override
public void run() {
// Use your variable
}
}

Local variables that are declared as final will be visible in the thread:
void doSomething(final String foo) {
new Thread(new Runnable() {
#Override
public void run() {
// SOME CODE HERE REQUIRES VARIABLE
System.out.println(foo);
}
}).start();
}

Can someone please explain how to do this.
So your problem has more solutions but nicely from the beginning. I suggest you to create own subclass of Thread and pass parameter via its constructor.
public class MyThread extends Thread {
public MyThread(String value) {
}
}
Or you can also use Runnable interface as well.
public class MyThread implements Runnable { ... }
Update:
Or like #erickson pointed out you can wrap your code into body of method but as method's argument you have to pass final variable because you cannot cannot refer to a non-final variable inside inner class defined in a different method.

You can't pass argument using anonymous classes in Java. What you can do is create a separate class and pass it as instance variable

String foo = "hello world";
final String parameter = foo;
new Thread(new Runnable() {
#Override
public void run() {
//Use parameter
}
}).start();

Related

How can i call extra method that i define in anonymous class? [duplicate]

This question already has answers here:
Can I access new methods in anonymous inner class with some syntax?
(7 answers)
Closed 6 years ago.
My example shows i try to add some extra method to Runnable anonymous class, in general how can i call extra method which i create.
Runnable myRunnable = new Runnable()
{
public void run()
{
System.out.println("Running");
}
// any extra method to explain the question
public void a()
{
System.out.println("A");
}
};
myRunnable.run();
myRunnable.a(); // is this right??
Why would you even be able to do such a thing? your myRunnable object is of type java.lang.Runnable. It doesn't have any other methods than what already exists there. Java cannot know at runtime that the actual object which is assigned to myRunnable is actually your own implementation.
However, you can do something like this:
class MyRunnable implements Runnable {
#Override
public void run() { }
public void myMethod() { }
}
And then
MyRunnable mr = new MyRunnable();
mr.myMethod();

Define method with object instantiation in java

I'm slowly transitioning from C++ to java and I do not understand the following piece of code:
public class TestThread
{
public static void main (String [] args)
{
Thread t = new MyThreads()
{
public void run()
{
System.out.println(" foo");
}
};
t.start();
System.out.println("out of run");
}
}
An object type "MyThreads" is being instantiated, but what does the function "void run" mean?
Why is it written using that syntax right after the object instantiation?
Is that function being overriden?
When is this kind of syntax (where I define a function with an object instantiation) necessary/required? and where is it preferred/useful?
It means that the class MyThreads either require you to first write a method with name run or the way you are doing provides the ability to change the existing run method behaviour where you are declaring.
It is like overriding if run method is already there or creating the method when you want to create object.
This provides the ability to create objects of MyThreads without having to change the original class or creating multiple classes.
public class TestThread
{
public static void main (String [] args)
{
Thread t = new MyThreads()
{
public void run()
{
System.out.println(" foo");
}
};
t.start();
Thread t1 = new MyThreads()
{
public void run()
{
System.out.println(" this time it is somethidn else");
}
};
t1.start();
System.out.println("out of run");
}
}
Little modification to your code shows the advantage of having this feature. If you observe run method of t1 is doing something different than what is in t. So it is now completely new thread.
This code is equivalent to
public class TestThread
{
static class MyThreadSubclass extends MyClass {
public void run() {
System.out.println("foo");
}
}
public static void main (String [] args)
{
Thread t = new MyThreadSubclass();
t.start();
System.out.println("out of run");
}
}
It's just a convenient way of defining a subclass inline, without having to give it a name; it's just syntactic sugar. It's creating an object of a subclass that overrides the method run() from MyThreads.

Unable to access global variables via Runnable in class

Good Day,
I have a class called FunctionHandler, that contains a method called evaluate like this:
class FunctionHandler{
Object globalVar;
public void Evaluate(){
ThreadPool pool;
Runnable task = new Runnable(){
public void run() { aWorkerTask(globalVar); }
}
pool.start(task);
pool.stop();
}
public void aWorkerTask(Object object){//worker stuff}
}
The problem is, my Runnable object can't seem to access globalVar! It seems to be it's own object somehow that can't reference what is inside it's class. Is there anyway around it?
The problem is that this code inherently doesnt work. Runnable cannot access globaVar. I need aWorkerTask to be wrapped in a Runnable and it needs access to globalVar
I'm not sure if this is the best implementation, but what I did was to create a class that implements Runnable as such:
public class MyRunnable implements Runnable {
private FunctionHandler functionHandler; //Global Reference - Only reading from it
private Object globalVar;
public MyRunnable(FunctionsHandler functionsHandler,Object globalVar) {
this.functionsHandler = functionsHandler;
this.globalVar = globalVar;
}
public void run(){
functionHandler.aWorkerTask(globalVar)
}
}
And pass in the main object functionHandler, which contains the function I need to make as a Runnable.
I then create a runnable as such:
MyRunnable taskProcessor = new MyRunnable(this,variableName,functionValues,jobNum.toString());
threadPool.runTask(taskProcessor);
A Runnable object is indeed its own object. Your options are to set it via a mutator or declare globalVar as final. Here's the mutator solution, in case you don't want globalVar to be final:
public void startRun() {
Object globalVar = new Object();
Runnable run = new Runnable() {
Object localVar;
public Runnable prepare(Object param) {
localVar = param;
return this;
}
#Override
public void run() {
/* Do your stuff */
}
}.prepare(globalVar);
}
Note that if you do this and you want globalVar to be modifiable both inside and outside the thread, you'll need to wrap it in a suitable dereferencing object.
If you want runnables to be able to access class variables, they have to be static; just change your code to:
static Object globalVar;

Callback from new thread to class from which thread was initiated

I have a class from which I am calling a new thread.
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
//After this I would like to notify my MainClass that some thing has been done and pass a value.
}
}
}
private void callbackFunc(int a){
// Do something based on value of a
}
}
I have a function in my MainClass. But how do i call this function from my new thread, so as to receive a callback.
Thanks.
You should just be able to call the method in MainClass by its name just as if you were calling from directly inside MainClass itself (as opposed to from the inner class).
If a method name you want to call happens to conflict with one that your inner class has inherited from Object then you can prefix the call with MainClass.this, e.g. MainClass.this.toString() calls toString on MainClass, whereas just toString() calls it on the inner class instance.
In such a case pass the instance of MainClass to the thread class ((during creation)) so that it can call method on it. Having inner class as suggested by others is also a good option.
Something similar-
class MainClass {
private void cleardata() {
new Thread(new MyThread(this)).start();
}
}
class MyThread implements Runnable {
private MainClass mc;
MyThread(MainClass mc) {
this.mc = mc;
}
public void run() {
// do something
// mc.someMethod();
}
}
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
callBackFunc(result);
}
}
}
private void callBackFunc(int a) {
}
}
Just do it:
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
notifyTheClass("a parameter");
}
}
private void notifyTheClass(String aParam) {
//..do something else
}
}
}
But it is not related to threads, this is about inner classes. If you want the main thread to wait until the new thread is finishes, use Futures for a result. Or use some other multithreading primitives.

Put Java Threading Class into a separate class

Consider following SWT code example:
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet151.java?view=co
How can I separate the inline defined class?
Thread thread = new Thread() {
public void run() {
...
}
};
I want to define a separate class which updates the table just like it does here. How do I pass the list back to the table? Example code?
Just create a class which extends Thread.
public class Task extends Thread {
public void run() {
// ...
}
}
and create it as follows:
Task task = new Task();
The normal practice is however to implement Runnable:
public class Task implements Runnable {
public void run() {
// ...
}
}
Or if you want a Thread which returns a result, implement Callable<T> where T represents the return type.
public class Task implements Callable<String> {
public String call() {
// ...
return "string";
}
}
Both can be executed using the ExecutorService.
I would not create a class that extends Thread. It's more likely that you'll have a class that implements Runnable and provides access to private data members:
public class YourTask implements Runnable
{
private ResultClass result;
public void run() { }
public ResultClass getResult() { return result; }
}
Have a look at java.util.concurrent packages and the new FutureTask. I think that's a better bet.
You can work passing parameters or setting globally visible attributes, example:
class Foo
{
public static String baz = "baz";
private String bar = "bar";
void startThread()
{
MyThread thread = new MyThread(bar);
thread.start();
}
}
class MyThread extends Thread
{
String ref;
MyThread(String ref)
{
this.ref = ref;
}
public void run()
{
// it can work with passed parameter
System.out.println(ref);
// but also with globally visible variables
System.out.println(Foo.baz);
}
}

Categories