Changes made in Thread via ExecutorService not reflecting after execution - java

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

Related

Retrieving result from List List<Future<Callable<Integer>>>

Task:
You are given a List of Future objects that return Callable. You should execute these Callable objects in the reverse order, starting from the end of the List and return a sum of values returned by these Callable objects.
Method to implement:
import java.util.concurrent.*;
class FutureUtils {
public static int executeCallableObjects(List<Future<Callable<Integer>>> items) {
// write your code here
}
}
so, the question is how to retrieve the results of Callable tasks correctly
What I understand:
1) In order to submit Callable we need to use
ExecutorService exec = Executors.newFixedThreadPool(4);
exec.submit(put Callable);
2) In order to retrieve result of Callable execution, we need to use Future object;
I understand how to retrieve results from the Callable list but not from >>
I believe I miss something.
This is the code I wrote trying to understand how to complete the task
public static void main(String[] args) throws InterruptedException, IOException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
List<Future<Callable<Integer>>> list = new ArrayList<>();
Future first = executorService.submit(new PrintIfPrimeTask(1));
list.add(first);
try {
ExecutorService exec = Executors.newFixedThreadPool(4);
Future<Callable<Integer>> good = list.get(0);
Callable<Integer> temp = good.get();
Future<Integer> kek = exec.submit(temp);
Integer a = (Integer) kek.get();
System.out.println(a);
} catch (Throwable e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
It gives
java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to java.base/java.util.concurrent.Callable
at Solution.main(Solution.java:36)
PrintIfPrimeTask does nothing but return 2
class PrintIfPrimeTask implements Callable<Integer> {
private final int number;
public PrintIfPrimeTask(int number){
this.number = number;
}
#Override
public Integer call() throws Exception {
return 2;
}
}

Muti thread join & get return values

I'm trying to do multiple heavy calculations using threads.
Then I need to do something with the results after making sure all threads have finished its job.
Here's the basic code:
private class Runner implements Runnable {
private String _result = "fail";
public String get_results() {
return _result;
}
public void run() {
_result = "do complex calculation";
}
}
public void test() {
List<Thread> threads = new ArrayList<Thread>();
List<Runner> threadObjects = new ArrayList<Runner>();
for (int i = 0; i < 10; i++) {
Runner runner = new Runner();
Thread t = new Thread(runner);
t.start();
threads.add(t);
threadObjects.add(runner);
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException ex) {
}
}
for (Runner threadObject : threadObjects) {
System.out.println(threadObject.get_results());
}
}
My question is, is above snippet a common or a good approach to get calculation value?
If not please suggest a better ones.
Also sometimes I got runner.get_results() reponse = "fail", it seems calculation does not processed at all.
Thanks
You can use an ExecutorService such as the ScheduledThreadPoolExecutor;
ExecutorService executor = new ScheduledThreadPoolExecutor(numOfThreads);
With numOfThreads being the number of threads you want sitting in the thread pool.
You can then use the submit(Callable<T> task) method provided by the ScheduledThreadPoolExecutor class to execute the calculation.
You would then have a Callable implementation of your calculation and pass it to the submit() method in ExecutorService to execute the calculation;
class Calculation implements Callable {
#Override
public Object call() throws Exception { // The signature can be changed to return a different type (explained at the end)
return "do complex calculation";
}
}
As we can see from the method signature of the submit(Callable<T> task) method it returns a Future.
public <T> Future<T> submit(Callable<T> task)
The get() method of the Future class will return the result upon successful completion. This would ensure that your calculation completed before reading it.
A further note on the return type of the call() method;
Although this returns Object there is nothing stopping you changing the type of object it returns (this is known as co-variant returns)
For example the following is perfectly legal:
#Override
public String call() throws Exception {
return "do complex calculation";
}

How to pass a parameter to a thread and get a return value?

public class CalculationThread implements Runnable {
int input;
int output;
public CalculationThread(int input)
{
this.input = input;
}
public void run() {
output = input + 1;
}
public int getResult() {
return output;
}
}
Somewhere else:
Thread thread = new Thread(new CalculationThread(1));
thread.start();
int result = thread.getResult();
Of course, thread.getResult() doesn't work (it tries to invoke this method from the Thread class).
You get what I want. How can I achieve this in Java?
This a job for thread pools. You need to create a Callable<R> which is Runnable returning a value and send it to a thread pool.
The result of this operation is a Future<R> which is a pointer to this job which will contain a value of the computation, or will not if the job fails.
public static class CalculationJob implements Callable<Integer> {
int input;
public CalculationJob(int input) {
this.input = input;
}
#Override
public Integer call() throws Exception {
return input + 1;
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
Future<Integer> result = executorService.submit(new CalculationJob(3));
try {
Integer integer = result.get(10, TimeUnit.MILLISECONDS);
System.out.println("result: " + integer);
} catch (Exception e) {
// interrupts if there is any possible error
result.cancel(true);
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.SECONDS);
}
Prints:
result: 4
The accepted answer is great. But it is not the simplest approach. There's no real need to use an ExecutorService if you just want to wait for the result of a thread. You can simply use java.util.concurrent.FutureTask, which is basically a Runnable wrapping a Callable which also implements the Future interface.
So step 1 is still make the calculation a Callable :
public class Calculation implements Callable<Integer> {
private final int input;
public Calculation(int input) {
this.input = input;
}
#Override
public Integer call() throws Exception {
return input + 1;
}
}
So where you need the asynchronous calculation you can do :
FutureTask<Integer> task = new FutureTask<>(new Calculation(1561));
new Thread(task).start();
// ... do other stuff
// when I really need the result :
try {
int result = task.get(); // this will wait for the task to finish, if it hasn't yet.
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
e.getCause().printStackTrace(); // e.getCause() holds the exception that happened on the calculation thread
}
What the ExecutorService adds is managing a pool of threads to run the task on, but under the hood of an ExecutorService, basically the same thing happens.
You are looking for Callable. It's a Runnable on steroids, it can return a result. Check the javadoc:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html
Here is a tutorial: http://www.journaldev.com/1090/java-callable-future-example
Old school style
public class CalculationThread extends Thread {
int input;
int output;
public CalculationThread(int input){
this.input = input;
}
public void run() {
output = input + 1;
}
public int getResult() {
return output;
}
}
CalculationThread thread = new CalculationThread(1);
thread.start();
thread.join();
int result = thread.getResult();
Use constructor and pass value by reference.
public CalculationThread(int[] input)
Do you want to pass the value of int to the thread called CalculationThread you should create a thread but if you pass a parameter by value the thread can use that value but you can't get the data back. Passing it by reference you can modify the value but not reference in the thread and the reference if it's available to both threads point to the value which is modifiable in both threads. Of cause you code should be synchronized to share the same reference.

How to get the variables out of a new thread?

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

What does 'result' in ExecutorService.submit(Runnable task, T result) do?

Looking at the javadocs it just says
<T> Future<T> submit(Runnable task, T result)
Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return the given result upon successful completion.
Parameters:
task - the task to submit
result - the result to return
but what does it do with result? does it store anything there? does it just use the type of result to specify the type of Future<T>?
It doesn't do anything with the result - just holds it. When the task successfully completes, calling future.get() will return the result you passed in.
Here is the source code of Executors$RunnableAdapter, which shows that after the task has run, the original result is returned:
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
And yes, the generic type of the result should match that of the returned Future.
Runnable does not return anything and Future must return something so this method allows you to predefine the result of the returned future.
If you don't want to return a thing you can return null and I think the Void type exists to express that kind of things.
Future<Void> myFuture = executor.submit(myTask, null);
You know myFuture.get() will return null in this case but only after the task has been run, so you would use it to wait and throw any exception that were thrown in the task.
try {
myFuture.get();
// After task is executed successfully
...
} catch (ExecutionException e) {
Throwable c = e.getCause();
log.error("Something happened running task", c);
// After task is aborted by exception
...
}
You can mutate the object that was passed-in during the task. For example:
final String[] mutable = new String[1];
Runnable r = new Runnable() {
public void run() {
mutable[0] = "howdy";
}
};
Future<String[]> f = executorService.submit(r, mutable);
String[] result = f.get();
System.out.println("result[0]: " + result[0]);
When I run this code it outputs:
result[0]: howdy

Categories