Am I using callable and futures multithreading the right way (java)? - java

I need some tasks to be done multi threaded.
I know in advance that i will continue with my program when all tasks are completed.
Is the following code right for this purpose?
public void test() {
Callable<String> myCall = new Callable() {
#Override
public String call() throws Exception {
return doDomething();
}
};
Callable<String> myCall2 = new Callable() {
#Override
public String call() throws Exception {
return doDomething2();
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Callable<String>> list = Arrays.asList(myCall,myCall2);
List<Future<String>> futuresList = executor.invokeAll(list);
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(0).get();
//...
}
I'm trying to change this to work with generics:
public void test() {
Callable<?> myCall = new Callable() {
#Override
public String call() throws Exception {
return doDomething();
}
};
Callable<?> myCall2 = new Callable() {
#Override
public String call() throws Exception {
return doDomething2();
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Callable<?>> list = Arrays.asList(myCall,myCall2);
List<Future<?>> futuresList = executor.invokeAll((Collection<? extends Callable<?>>)list);
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(0).get();
// ...
}
I get the following compilation error:
The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Collection<capture#2-of ? extends Callable<?>>).

Aside from you accessing the zeroth index twice I dont see anything wrong with it.
This edit is in regards to your question on how to implement it without the ExecutorService. As ColinD notes, you really shouldn't I will show why
To get the same set of functionality you would need two Objects and use two threads as a latch
String result1 = null;
String result2 = null;
public void test() {
Thread thread1 = new Thread(new Runnable(){
public void run(){
result1 = doSomething();
}
});
Thread thread2 = new Thread(new Runnable(){
public void run(){
result2 = doSomething2();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
...
...
}
Now what if you want to add another thread/unit-of-work then you need
Thread thread3 = new Thread(new Runnable(){
public void run(){
result3 = doSomething3();
}
});
thread3.start();
thread3.join();
And so forth. Hence your solution is the better way to do this.

Well, let me be devil's advocate then.
The only thing in this example that actually can hit right back at you is the fact that you are calling two methods a-sychronously which is probably not that obvious to other programmers.
I guess this is just an example, but other programmers might not recognize that doSomething and doSomething2 should not have 'shared mutable state' since they are executed a-synchronously. It's not that obvious in this setup.
So I would recommend to actually put the logic in separate classes.

Related

ExecutorService thread safety

Let's say I have an instance of ExecutorService from one of Executors static factory methods.
If I submit a Callable where RetVal is not a thread-safe, locally instantiated object from some thread, do I need to worry about RetVals' integrity when I get() it from the same thread? People say that local variables are thread-safe, but I am not sure if it applies when you're returning a locally instantiated Object and receiving it from some other thread.
Here's an example similar to my situation:
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<List<String>> fut = executor.submit(() -> {
List<String> ret = new ArrayList<>();
ret.add("aasdf");
ret.add("dfls");
return ret;
});
List<String> myList = fut.get();
In the above example, I'm retrieving an ArrayList that was created in a different thread--one created by executor. I don't think above code is thread safe but I was not able to find much information regarding my specific situation.
Now I tried the above code on my computer and it actually returned the expected result 100% of the time I tried it, and I even tried with my own implementation of an ExecutorService and so far I have only got the expected results. So unless I have gotten extremely lucky I am pretty sure it works but I'm not sure how.
I created a not thread-safe object in another thread and received it in another; shouldn't I have a chance to have received a partially constructed object--in my case a list that does not contain 2 strings?
Below is my custom implementation I made just to test. You can ignore the EType enum thingy.
class MyExecutor {
enum EType {
NoHolder, Holder1, Holder2
}
private ConcurrentLinkedQueue<MyFutureTask<?>> tasksQ;
private final Thread thread;
private final EType eType;
public MyExecutor(EType eType) {
eType = Objects.requireNonNull(eType);
tasksQ = new ConcurrentLinkedQueue<>();
thread = new Thread(new MyRunnable());
thread.start();
}
public <T> Future<T> submit(Callable<T> c) {
MyFutureTask<T> task = new MyFutureTask<T>(c, eType);
tasksQ.add(task);
return task;
}
class MyRunnable implements Runnable {
#Override
public void run() {
while (true) {
if (tasksQ.isEmpty()) {
try {
Thread.sleep(1);
continue;
} catch (InterruptedException ite) {
Thread.interrupted();
break;
}
}
MyFutureTask<?> task = tasksQ.poll();
try {
task.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class MyFutureTask<T> implements RunnableFuture<T> {
final Callable<?> cb;
volatile Object outcome;
static final int STATE_PENDING = 1;
static final int STATE_EXECUTING = 2;
static final int STATE_DONE = 3;
final AtomicInteger atomicState = new AtomicInteger(STATE_PENDING);
final EType eType;
public MyFutureTask(Callable<?> cb, EType eType) {
cb = Objects.requireNonNull(cb);
eType = Objects.requireNonNull(eType);
}
#Override
public boolean cancel(boolean mayInterruptIfRunning) {
throw new NotImplementedException();
}
#Override
public boolean isCancelled() {
return false;
}
#Override
public boolean isDone() {
return atomicState.get() == STATE_DONE;
}
#SuppressWarnings("unchecked")
#Override
public T get() throws InterruptedException, ExecutionException {
while (true) {
switch (atomicState.get()) {
case STATE_PENDING:
case STATE_EXECUTING:
// Thread.sleep(1);
break;
case STATE_DONE:
return (T)outcome;
default:
throw new IllegalStateException();
}
}
}
#Override
public T get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
throw new NotImplementedException();
}
void set(T t) {
outcome = t;
}
#Override
public void run() {
if (atomicState.compareAndSet(STATE_PENDING, STATE_EXECUTING)) {
Object result;
try {
switch (eType) {
case NoHolder:
result = cb.call();
break;
case Holder1:
throw new NotImplementedException();
case Holder2:
throw new NotImplementedException();
default:
throw new IllegalStateException();
}
} catch (Exception e) {
e.printStackTrace();
result = null;
}
outcome = result;
atomicState.set(STATE_DONE);
}
}
}
}
class MyTask implements Callable<List<Integer>> {
#Override
public List<Integer> call() throws Exception {
List<Integer> ret = new ArrayList<>(100);
IntStream.range(0, 100).boxed().forEach(ret::add);
return ret;
}
}
The important thing is the happens-before relationship. From ExecutorService API docs:
Memory consistency effects: Actions in a thread prior to the
submission of a Runnable or Callable task to an ExecutorService
happen-before any actions taken by that task, which in turn
happen-before the result is retrieved via Future.get().
So you are safe to transfer a mutable object like this. The ExecutorService implementation transfers the object via some form of safe publication.
Obviously, don't update the object in the original thread after returning it.
If you were to communicate between threads by stashing in a shared non-volatile field, then that would be unsafe.
Thread safety becomes a concern when multiple threads try to access and modify the same state simultaneously.
Note that you will not get hold of the actual result from a Future until the task is finished (i.e. Future#get will not return until the task is finished).
In your first example, thread safety is not an issue because the a new object (while mutable) is created by one thread (the thread created by the Executor) and retrieved from the Future object once that thread has finished processing the task. Once the calling thread gets hold of the object, it cannot be modified by any other thread, because the creating thread no longer has access to the List.

How does java differentiate Callable and Runnable in a Lambda?

I got this little code to test out Callable. However, I find it pretty confusing how the Compiler could know if the Lambda is for the Interface Callable or Runnable since both don't have any parameter in their function.
IntelliJ, however, shows that the Lambda employs the code for a Callable.
public class App {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(() ->{
System.out.println("Starting");
int n = new Random().nextInt(4000);
try {
Thread.sleep(n);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println("Finished");
}
return n;
});
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES );
}
}
See the documentation of ExecutorService which has 2 submit methods with one parameter:
submit(Callable<T> task) using Callable<T> which has method call() returning T.
submit(Runnable task) usnig Runnable which has method run() returning nothing (void).
Your lambda gives an output, returns something:
executorService.submit(() -> {
System.out.println("Starting");
int n = new Random().nextInt(4000);
// try-catch-finally omitted
return n; // <-- HERE IT RETURNS N
});
So the lambda must be Callable<Integer> which is a shortcut for:
executorService.submit(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
System.out.println("Starting");
int n = new Random().nextInt(4000);
// try-catch-finally omitted
return n;
}}
);
To compare, try the same with Runnable and you see it's method's return type is void.
executorService.submit(new Runnable() {
#Override
public void run() {
// ...
}}
);
The main difference in the signature is that a Callable returns a value while a Runnabledoes not. So this example in your code is a Callable, but definately not a Runnable, since it returns a value.

How to return value from Runnable Interface using FutureTask

I did lot of google but I could not find how to return value from Runnable interface using FutureTask.
I need to return outcome of run method using FutureTask, I know that same can be archived using Callable Interface but how it can be done using Runnable Interface.
FutureTask constructor accepts second parameter for return value.
public FutureTask(Runnable runnable,V result)
How to assign outcome of run() method to V result.
FutureTask<String> futureTask=new FutureTask<String>(new Runnable() {
#Override
public void run() {
String outcome="Task Completed Successfully";
}
},null);
I am using
ExecutorService exec = Executors.newSingleThreadExecutor(new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
Future fs = exec.submit(new Callable() {
public Object call() throws Exception {
return null;//yourObject
}
});
fs.get();//your object
The null value in your call is the return value. To have it return "Task Completed Successfully", you'd need:
FutureTask<String> futureTask=new FutureTask<String>(new Runnable() {
#Override
public void run() {
}
}, "Task Completed Successfully");
This is clearly not very useful if you want the Runnable to compute a result, however.
Use a Callable, instead.

How to get the output stream from a thread

I currently have several runnable classes, each printing a string upon completion using System.out.println().
In the main() I execute them using a ExecutorService ,executor.execute() for each of them.
I am wondering after executing those threads, how to get the output stream from them for future use ?
Pretty much like using .getInputStream for processes but there's no such method in the Thread class. Thanks!
There's a class which implements runnable interface like this:
public class A implements Runnable {
public void run() {
System.out.println(5); //this thread always print out number 5
}
}
and in the main function I need to get the printed number and store it
public static void main(String[] args) {
ExecutorService ThreadPool = Executors.newFixedThreadPool(1);
ThreadPool.execute(new A()); //This statement will cause the thread object A
//to print out number 5 on the screen
ThreadPool.shutdown();
......
}
Now I need to get the printed number 5 and store it into, say an integer variable.
I think below code will satisfy your requirement.
class MyCallable implements Callable<InputStream>
{
#Override
public InputStream call() throws Exception {
//InputStream inputStreamObject = create object for InputStream
return inputStreamObject;
}
}
class Main
{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<InputStream>> list = new ArrayList<Future<InputStream>>();
for (int i = 0; i < 25; i++) {
Callable<InputStream> worker = new MyCallable();
Future<InputStream> submit = executor.submit(worker);
list.add(submit);
}
InputStream inputStreamObject = null;
for (Future<InputStream> future : list) {
try {
inputStreamObject = future.get();
//use inputStreamObject as your needs
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
Runnable and Callable in thread:
runnable interface has a method public abstract void run(); void - which means after completing run method, it will not return anything. Callable<V> interface has a method V call() throws Exception; which means after completing call method, it will return Object V that is parametrized as
public class Run_Vs_Call {
public static void main(String...args){
CallableTask call = new CallableTask();
RunnableTask run = new RunnableTask();
try{
FutureTask<String> callTask = new FutureTask<String>(call);
Thread runTask = new Thread(run);
callTask.run();
runTask.start();
System.out.println(callTask.get());
}catch(Exception e){
e.printStackTrace();
}
}
public static class CallableTask implements Callable<String>{
public String call( ){
String stringObject = "Inside call method..!! I am returning this string";
System.out.println(stringObject);
return stringObject;
}
}
public static class RunnableTask implements Runnable{
public void run(){
String stringObject = "Inside Run Method, I can not return any thing";
System.out.println(stringObject);
}
}
}
you can use new static class:
public class Global{
//example
public static ..
public static ..
}

Access outer variable from inner anonymous Runnable

The following example code (SSCCE) complains that local variable a must be final.
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
A a;
Thread t = new Thread(new Runnable() {
public void run() {
a = list.get(0); // not good !
}
});
t.start();
t.join(0);
System.out.println(a);
}
class A {}
}
To make things working i change the code to that one
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
// A a;
final ObjectRef x = new ObjectRef();
Thread t = new Thread(new Runnable() {
public void run() {
// a = list.get(0);
x.set(list.get(0));
}
});
t.start();
t.join(0);
// System.out.println(a);
System.out.println(x.get());
}
class A {}
class ObjectRef<T> {
T x;
public ObjectRef() {}
public ObjectRef(T x) { this.x = x; }
public void set(T x) { this.x = x; }
public T get() { return x; }
}
}
My questions:
Is there something wrong with this ?
The ObjectRef class exists as standard class in JSE ?
What is the right way ?
Right way is using FutureTask and Callable
FutureTask task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
Executor ex = Executors.newFixedThreadPool(1);
ex.execute(task);
// do something else, code is executing in different thread
A a = task.get(); //get result of execution, will wait if it's not finished yet
ex.shutdown();
Did you consider using Callable instead? Callable can be used when you produce a result, which seem to be your case.
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
Callable<A> call = new Callable<A> {
A call() throws Exception
{
// do something with the list
return list.get(0);
}
}
ExecutorService executor = new ScheduledThreadPoolExecutor(1);
Future<A> future = executor.submit(call);
System.out.println( future.get() );
}
I agree that you should go with Callable and FutureTask.
But it may not be necessary to use an Executor: If you are not going to share that Executor with other code, the three lines required to create it, submit the task, and then shut it down again, seem too verbose. You could just use a Thread.
FutureTask<A> task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
new Thread(task).start();
A result = task.get();

Categories

Resources