My setup is as described. What I want to accomplish is have the aMethod in each of my implemented classes to run in parallel. I have looked into using Futures and Runnable and I am unsure how to proceed with either process.
My first thought was try to return a Future<Boolean> instead of a regular boolean, but I am unsure as to how would I associate the result with the name that it was initially called with.
The reason why I want aMethod to run in parallel/asynchronous is because aMethod might have a http request. If there is a request, I do not want to wait for a reply to continue. I want it to do that in a separate thread and continue on to the next method.
With a lot of http requests, aClass.doMethod() takes a while to accomplish. I want to run them in parallel so I don't have to wait for each http request before continuing.
Anyone have tips on how to accomplish this?
import java.util.ArrayList;
import java.util.List;
//Strategy.java
public interface Strategy {
boolean aMethod();
}
//AStrategy.java
public class AStrategy implements Strategy {
#Override
public boolean aMethod() {
// Do a couple http requests
return true;
}
}
//BStrategy.java
public class BStrategy implements Strategy {
#Override
public boolean aMethod() {
// Do some other requests
return true;
}
}
//SomeClass.java
public class SomeClass {
String name;
Strategy aStrategy;
public SomeClass(String name, Strategy strategy) {
this.name = name;
this.aStrategy = strategy;
}
public boolean doMethod() {
return aStrategy.aMethod();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//Just a regular pojo
//ResultsClass.java
public class ResultsClass {
String name;
boolean result;
public ResultsClass(String name, boolean result) {
this.name = name;
this.result = result;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isResult() {
return result;
}
public void setResult(boolean result) {
this.result = result;
}
}
public class AClass {
public static void main(String args[]) {
List<SomeClass> classes = new ArrayList<>();
classes.add(new SomeClass("Class 1", new AStrategy()));
classes.add(new SomeClass("Class 2", new BStrategy()));
List<ResultsClass> results = new ArrayList<>();
classes.forEach(aClass -> results.add(new ResultsClass(aClass.getName(), aClass.doMethod())));
}
}
The simplest way for you to do this is probably to use a ThreadPoolExecutor, make your strategy classes runnable or wrap them in runnables, and submit them to the executor. Once all are submitted, you can block on the futures until the threads complete and you can retrieve the results from the futures.
Related
I'm working on a class that will get a list of strings and process them asynchronously using CompletableFutures. Each string is processed by invoking another class that will perform several operations and return a response or throw an exception if there is an error.
I would like to aggregate the responses that I get, whether they have a valid response or an exception and return them as a list to the caller. I would like the caller to be able to expect a list of SomeResponse and be able to interpret them using polymorphism.
However, I'm stuck on determining if this can be done using polymorphism at all, given that the fields for the success and error response are completely different. I have added some pseudo code below on one alternative I have thought of. Basically have SomeResponse be an interface with an isSuccess method. This will allow the caller to know if it's an error or not. However, the caller would still have to cast it to the correct implementation in order to get the value or the error. Is there a better way to approach this? My requirement is being able to return both a success and error response for each given request in the list. If there is an exception, we don't want to abort the entire operation.
public MyProcessorClass {
private final SomeOtherClass someOtherClass;
public List<SomeResponse> process(List<String> requestList) {
return requestList.stream().map(this::procesRequest)
.collectors(Collect.tolist()):
}
private processRequest(String request) {
CompletableFuture completableFuture = CompletableFuture
.supplyAsync(() => {
return new SomeSuccessResponse(someOtherClass.execute(request));
})
.exceptionally(e -> {
return new SomeErrorResponse(e.getCause);
});
return completableFuture.get();
}
}
public interface SomeResponse {
boolean isSuccess();
}
public class SomeSuccessResponse implements SomeResponse {
private final String value;
#Getter
private final boolean success;
public SomeSuccessResponse(String value) {
this.value = value;
this.success = true;
}
}
public class SomeErrorResponse implements SomeResponse {
private final Throwable error;
#Getter
private final boolean success;
public SomeErrorResponse(Throwable error) {
this.error = error;
this.success = false;
}
}
What you want is the visitor pattern https://en.wikipedia.org/wiki/Visitor_pattern
public class Main {
interface IResponse {
void acceptHandler(IResponseHandler handler);
}
static class ResponseA implements IResponse {
#Override
public void acceptHandler(IResponseHandler handler) {
handler.handle(this);
}
}
static class ResponseB implements IResponse {
#Override
public void acceptHandler(IResponseHandler handler) {
handler.handle(this);
}
}
public interface IResponseHandler {
void handle(ResponseA response);
void handle(ResponseB responseB);
}
public static void main(String[] args) {
final IResponseHandler handler = new IResponseHandler() {
#Override
public void handle(ResponseA response) {
System.out.println("Handle ResponseA");
}
#Override
public void handle(ResponseB responseB) {
System.out.println("Handle ResponseB");
}
};
final IResponse someResponse = new ResponseA();
someResponse.acceptHandler(handler);
}
}
In my use case, I want to return a user object from the lambda function as in the code below. Before posting my question, I try many similar questions like this and this but no theme solves my problem, here is my code:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class AppDatabase {
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
}
public class MyClass {
private User mUser;
public User findUser(){
AppDatabase.databaseWriteExecutor.execute(() -> {
mUser = work();
});
return mUser;
}
public User work(){
//simulate get user from database
User user = new User();
user.setName("Toto");
return user;
}
}
public class Main {
public static void main(String[] args) {
MyClass myClass = new MyClass();
User user;
user = myClass.findUser();
System.out.println(user.getName()); //this line: Exception in thread "main" java.lang.NullPointerException
}
}
When I run this code, I get "Exception in thread" main "java.lang.NullPointerException". My question is how do I get the User object built by the work () function, but this function should run in a background thread like in code.
findUser returns right away, and it returns null because mUser hasn't been set yet. You need to either wait for it to be set, or return a Future<User> that the caller can wait on.
I have a list of urls and I want to hit them all in parallel and combine the result into a final Java object using Java spring RestTemplate. I'm able to achieve it buy accessing the urls in sequence, but due to performance concerns, I want to achieve them same in parallel. Looking forward to hearing your suggestions
You can use threads to perform parallel jobs.
First, make a result data class to handle the responses of your URLs
public class URLResult {
public String url;
public String response;
public Date responseTime;
// Add fields whatever you need
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
public Date getResponseTime() {
return responseTime;
}
public void setResponseTime(Date responseTime) {
this.responseTime = responseTime;
}
}
Then use it in your threads :
public List<URLResult> list = new ArrayList<>();
public synchronized void addToList(URLResult result) {
list.add(result);
}
public void hitUrl(String url) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
URLResult result = new URLResult();
//here, connect to your url, get the result then set your URLResult fields
addToList(result);
}
});
thread.start();
}
At the end of the process, you will have a "list" of your results.
I want to use java interface in a way that i will make a call defining interface in my other class like 'private SoapURL soapURL;' and than i can access any class's method for example : i want to use login:-
private SoapURL soapURL;
SoapUrl = LoginSoap ();
String nameSpace = soapURL.getMethodName();
String url = soapURL.getUrl();
Is there any way to do something like this. I am sorry i am not very good with Object Oriented principles but if there is a solution for my problem i would like to know it. Thanks in advance.
public interface SoapURL {
public String getNameSpace();
public String getUrl();
public String getSoapAction();
public String getMethodName();
public String getTag();
}
LoginSoap class
public class LoginSoap implements SoapURL {
#Override
public String getNameSpace() {
return "https://host.com/MobileWFC/";
}
#Override
public String getUrl() {
return "https://host.com/MobileWFC/MobileWS.asmx";
}
#Override
public String getSoapAction() {
return "https://host.com/MobileWFC/UserControl";
}
#Override
public String getMethodName() {
return "UserControl";
}
#Override
public String getTag() {
return "Login Activity";
}
}
SignUpSoap class
public class SignUpSoap implements SoapURL {
#Override
public String getNameSpace() {
return "https://host.com/MobileWFC/";
}
#Override
public String getUrl() {
return "https://host.com/MobileWFC/MobileWS.asmx";
}
#Override
public String getSoapAction() {
return "https://host.com/MobileWFC/UserRegister";
}
#Override
public String getMethodName() {
return "UserRegister";
}
#Override
public String getTag() {
return "SignUp Activity";
}
}
ResetPasswordSoap class
public class ResetPasswordSoap implements SoapURL {
#Override
public String getNameSpace() {
return "https://host.com/MobileWFC/";
}
#Override
public String getUrl() {
return "https://host.com/MobileWFC/MobileWS.asmx";
}
#Override
public String getSoapAction() {
return "https://host.com/MobileWFC/UserPasswordReset";
}
#Override
public String getMethodName() {
return "UserPasswordReset";
}
#Override
public String getTag() {
return "Forget Password Activity";
}
}
Your implementation looks correct. To make use of it, you can do this in main:
SoapURL reset = new ResetPasswordSoap();
System.out.println(reset.getUrl());
This is a method of minimizing coupling in large systems. And reduces dependency between objects by making use of a common interface for groups of objects that work together. You might be new at Object oriented principles, but you are one step ahead of the game already
To pass it to a function, you do:
public JPanel resetPass(SoapURL reset) {
...
}
// In main:
JPanel resetPassPanel = resetPass(reset);
Just do, for example:
SoapURL example = new LoginSoap();
String a = example.getTag();
a should be equal to "Login Activity"
The main use of Interface is polymorphism, or the ability to perform the same
operation on a number of different objects,
which is exactly what you wanted in your scenario
Your approach is absolutely fine , just a modification needed
private SoapURL soapURL;
//SoapUrl = LoginSoap (); // This line should be replaced with the Below line
soapURL=new LoginSoap();
String nameSpace = soapURL.getMethodName();
String url = soapURL.getUrl();
Since LoginSoap, SignUpSoap,ResetPasswordSoap classes are implemented classes of SoapURL Interface , thus reference variable of SoapURL can store Object of any of these child classes
soapURL=new LoginSoap();//soapURL.someMethod will call method of LoginSoapClass
soapURL=new SignUpSoap();// will call method of SignUpSoap class
soapURL=new ResetPasswordSoap();
I have a little question here.
private boolean isSomethingTrue(String param) {
boolean result = false;
myService.hasAlerts(param,new Callback<Boolean>(
#Override
public void onSuccess(Boolean hasAlerts) {
result = hasAlerts;
}
});
return result;
}
On this code, how can i return the boolean hasAlerts that is received in the callback?
This doesn't work because the result variable is not final.
But when it's final, it can't be modified so...
I've done something like that:
private boolean isSomethingTrue(String param) {
class ResultHolder {
boolean result=false;
}
final ResultHolder resultHolder = new ResultHolder();
myService.findBoolean(param,new Callback<Boolean>(
#Override
public void onSuccess(Boolean hasAlerts) {
resultHolder.result = hasAlerts;
}
});
return resultHolder.result;
}
But is there a simpler solution to handle such a case?
I've found this problem while trying to call a GWT RPC service.
I can think of a few variations--none of them particularly exciting. You could merge the result holder and callback into a single class and make it static if you could use it elsewhere, but it's not really an improvement.
private boolean isSomethingTrue(String param) {
class MyCallback implements Callback<Boolean> {
boolean result = false;
#Override
public void onSuccess(Boolean hasAlerts) {
result = hasAlerts;
}
}
final MyCallback callback = new MyCallback();
myService.findBoolean(param, callback);
return callback.result;
}
You could implement a generic synchronous Future, but that might be misleading.
Finally, if you're doing this often you could genericize the value holder.
public class Result<T> {
private T value;
public void set(T value) { this.value = value; }
public T get() { return value; }
}
private boolean isSomethingTrue(String param) {
final Result<Boolean> result = new Result<Boolean>();
myService.findBoolean(param,new Callback<Boolean>(
#Override
public void onSuccess(Boolean hasAlerts) {
result.set(hasAlerts);
}
});
return result.get();
}
What you need is a synchronous RPC. See >here< and >here< for details.
But I would prefer to change your coding style (assumed you have access to the code that is calling isSomethingTrue()). Supposed you have some code like this calling your method isSomethingTrue:
if(isSomethingTrue("foo")) {
doSomeCoolStuff();
}
You can transform this to a asynchronous coding style by changing it to something like this:
isSomethingTrue("foo", new Callback<Boolean>(
#Override
public void onSuccess(Boolean result) {
if(result) {
doSomeCoolStuff();
}
}
});
and
private void isSomethingTrue(String param, Callback callback) {
myService.hasAlerts(param,callback);
}