How to get the variables out of a new thread? - java

How can i get the variables out of a new thread created with:
public class ParseJson
{
public static String parsejson(String strHttpGet)
{
Thread thread = new Thread(new Runnable()
{
public String run(String strHttpGet)
{
String decodeJson = "someJson";
return decodeJson;
}
});
thread.start();
}
}
I mean how can i get back the decoded json to my function parseJson and give it back to my function call String decodedJson = ParseJson.parseJson(strHttpGet);?

In android, which you have tagged this question as, it would be simpler to use AsyncTask for this situation, because when you override the onPostEXecute method you can put in all sorts of things:
update the UI
send intents and messages
access variables of the parent class if the AsyncTask class is defined inside it.
class MyClass {
Button b;
boolean flag = false;
// Stuff
class MyAsyncClass extends AsyncTask {
// All the stuff, core work in doInBackground
#Override
void onPostExecute(/*vars*/) {
b.setText("Done");
flag = true;
}
}
}
General principles for using AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html
tutorial: http://samir-mangroliya.blogspot.co.uk/p/android-asynctask-example.html
tutorial: http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/

You can't return a value from a Thread in Java. Actually, run() doesn't have a return type.
You could use a shared custom Object that will hold the result. Declare it as final, so you can access it in the anonymous subclass (that would be equivalent to passing a reference to the subclass), and just call a setter on it when the work is done.
public class ParseJson {
public static String parsejson(final String strHttpGet) {
final StringHolder ob = new MyObject();
Thread thread = new Thread() {
public String run() {
String decodeJson = "someJson";
ob.setResult(decodeJson);
}
};
thread.start();
}
private static class StringHolder (){
private String result;
public String getResult() { return result; }
public void setResult(String r) { result = r; }
}
}
I'm not sure I understood why you said get back the decoded json to my function parseJson and give it back to my function call. Do you mean you'll just wait in that function until the Thread is finished? If that's what you want (again, why start a Thread?), you could use Thread.join().
Although if you want to get notified when the Thread finishes, you should indeed look into another option. Neil and Waqas have given good approaches.

You may even use an Observer/Observable pattern for this.

You could use a Future
public class Json {
private static final ExecutorService executor = Executors.newCachedThreadPool();
public static String parse(final String strHttpGet)
throws TimeoutException, InterruptedException, ExecutionException {
Future<String> jsonTask = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
String decodeJson = decodeJson(strHttpGet);
return decodeJson;
}
private String decodeJson(String strHttpGet) {
// TODO do actual parsing
return null;
}
});
// Allow the parsing to take one second
return jsonTask.get(1, TimeUnit.SECONDS);
}
}

Related

Changes made in Thread via ExecutorService not reflecting after execution

I have created a threadpool in Java with the help of ExecutorService and List of Futures.
I have created a RandomProcess class that implements Callable interface and overrides the call method
to perform certain operations.
It looks like this:
public class RandomProcess implements Callable<Integer> {
private Result result;
public RandomProcess(Result result) {
super();
this.result = result;
}
#Override
public Integer call() throws Exception {
//performSomeOps returns a Result that has certain values that I need
result = performSomeOps();
return 1;
}
I have this Result object in this class that is supposed to reflect the changes that were made
in the Randomprocess thread. unfortunately, the changes are not reflected when I return this Result.
public class Abc{
public Result check(){
Result result = new Result(true);
try {
ExecutorService exec = Executors.newFixedThreadPool(7);
List<Future<?>> futures = new ArrayList<Future<?>>(7);
for (Entity entity : randomListOfEntities) {
futures.add(exec.submit(new RandomProcess(result)));
}
for (Future<?> f : futures) {
f.get(); // wait for a process to complete
}
exec.shutdown();
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
Unable to figure out what the problem might be.
In Line result = performSomeOps();
you are not updating the value inside result that is being passed while submitting thread. You are just assigning new object at that line instead of changing the original object. You need to update the value inside result object(Something link result.setSomevalue() = performSomeOps().getSomeValue()) or pass your result object to performSomeOps(), and update result inside that method.
Need to Return "Result" as object from the "RandomProcess" Thread,Then Changes will be reflected.
public class RandomProcess implements Callable
{
private Result result;
public RandomProcess(Result result) {
super();
this.result = result;
}
#Override
public Result call() throws Exception {
result = performSomeOps();
return result;
}
}

Get Return Value from Runnable(Thread) in Java [duplicate]

This question already has answers here:
Returning value from Thread
(9 answers)
Closed 7 years ago.
Is there a way for me to pass the value of "r" once this thread completes? I believe I did this 9 or 10 months ago on another project but for the l ife of me I cannot remember the project of find the code. I've spent about 5 hours digging through code and googling but have fell short on a solution and since I do not develop in Java\Android often, this has completely slipped my mind.
Below is my code and what I think I remember from the last time I did this. I kind of remember a ".call()" or ".get()" but after trying to find something in the android docs. I'm not so sure. I could only find "callable".
public void updateUserProfile(){
if(checkFields(){
//Do Something
}else{
//Do Something
}
}
public boolean checkFields(){
Boolean r = false;
Runnable run = new Runnable(){
//Boolean r;
#Override
public void run() {
//Or boolean r;
//get value of r.
r = php.UpdateProfile.updateProfile(user_id, user_email);
}
};
new Thread(run).start();
return r; //run.get(r)?
}
What you are doing is creating an instance of an anonymous inner class implementing Runnable. As such you can access the fields of the containing class. Store the result of your code in one of those.
Of course be careful to synchronise access to this result variable between your main thread and the one you create here.
public class TestThreads {
static int r = 0;
public static void main(String[] args) {
Runnable run = new Runnable() {
public void run() {
r = 20;
}
};
Thread t = new Thread(run);
t.start();
try {
t.join();
}
catch(InterruptedException e) {
return;
}
System.out.println("Result: " + r);
}
}
You cannot return values from method which has return type Void.
Use Handler class to send messages, and from thread's run method, call handler.sendMessage() and handle this message on onHandleMessage of Handler
Handler Document link
Handler example
Try with Future, Callable, ExecuterService ... This might help http://www.journaldev.com/1090/java-callable-future-example
Runnable does not return. You will need to use Future that implements Callable or use FutureTask.
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
FutureTask<String> future =
new FutureTask(new Callable() {
public String call() {
String res = ...;
return res;
});
pool.execute(future);
String res = future.get();
// use the line below if you want to set a timeout for the task
String res = future.get(timeoutmillis, TimeUnit.MILLISECONDS);
I ended up using AsyncTask. Was hoping to keep it super simple because of support requirements but AsyncTask did what I needed it to.
private class updateUserProfile extends AsyncTask<Boolean, Boolean, Boolean>{
#Override
protected Boolean doInBackground(Boolean... params) {
return php.UpdateProfile.updateProfile(etEditAddress.getText().toString(),
etEditCity.getText().toString(),
spnStates.getSelectedItem().toString(), etEditZip.getText().toString(), etEditPhone.getText().toString(), etEditAddress.getText().toString());;
}
public void onPostExecute(String result) {
// execution of result of Long time consuming operation
Toast.makeText(MyAccount.this, result.toString(), Toast.LENGTH_LONG).show();
}
}

Make a copy object of anonymous thread

I am new to multi-threading,
and I am currently work on passing a parameter into a Thread.
public class MyRunnable<T> implements Runnable{
protected T obj;
public MyRunnable(){
obj= null;
}
#Override
public void run(){
//do something
}
public void setObj(T obj){
this.obj=obj;
}
public T getObj(){
return obj;
}
}
And I am try to initialize a MyRunnable obj with specify task
within the public void run , like this.
someMethod(new MyRunnable<someType>(){
public void run(){
// do some jobs 1.
// do some jobs 2.
}
});
I want to use this runnable object for different threads with different obj value,
so is it possible to make a deep copy with the same run method?
Thanks in advance!
edit:
the original MyRunnable().run() does nothing, and the task is implemented within the anonymous block, is it any work around to make the copy with the same implemented run() method?
You can make a copy constructor
public MyRunnable(MyRunnable myRunnable) {
this.fieldA = myRunnable.fieldA;
this.felddB = myRunnable.fieldB;
// etc
}
Because you'd be using a different object (with all of the other fields being the same), modify the constructor to reflect this
public MyRunnable(T obj, MyRunnable myRunnable) {
this.obj = obj;
this.fieldA = myRunnable.fieldA;
this.felddB = myRUnnable.fieldB;
// etc
}
You could create a method that returns a particular type of MyRunnable:
public MyRunnable<SomeType> getRunnableForSomePurpose(){
return new MyRunnable<SomeType>(){
public void run(){
//do some jobs
}
}
}
Then call that method each time you need a MyRunnable with that specific run method:
someMethod(getRunnableForSomePurpose());

How can I pass a parameter to a Java Thread?

Can anyone suggest to me how I can pass a parameter to a thread?
Also, how does it work for anonymous classes?
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();
}
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.
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.
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.
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();
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)
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();
}
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.
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.
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();
}
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.

How to notify all observers without holding the thread?

I have a thread inside a class like this-
import java.util.Observable;
public class Download extends Observable {
private int state = 0;
private final Thread myThread = new Thread(() -> {
/*
some work to do here
*/
setChanged();
notifyObservers(state);
});
public void download(int state) {
if (!myThread.isAlive()) {
this.state = state;
myThread.start();
}
}
public Thread getThread() {
return myThread;
}
public static void MyMethod() throws InterruptedException {
Download down = new Download();
down.addObserver((Observable ob, Object dat) -> {
System.out.println(ob);
if ((int) dat == 1) {
down.download(2);
} else {
System.out.println("success");
}
});
down.download(1);
down.getThread().join();
}
public static void main() throws InterruptedException {
MyMethod();
}
}
The problem is I never get it to print the "success" message.
I assume, it is because all observers are being notified from inside of MyThread. So when down.download(2) is called from the observer inside MyMethod(), the previous thread is still running and the call is ignored.
How can I notify all observers from the main thread, not from the myThread?
You are calling down.download(2) from within the execution of MyThread, therefore the thread is still alive which means that your download method does nothing because of if(!myThread.isAlive()).
I would recommend you to use the Executor framework and Listenable Futures from Guava instead of creating threads manually. Example code from the Guava wiki:
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
Note that Futures.addCallback(..) also has an overload which allows you to determine which executor should execute the callback, this seems to be what you want.

Categories