Resource management with Concurrency - java

ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Connection> task = () -> getConnection(); // a complicated method but safe from resource leaks
try (Connection connection = timeOut == null
? executor.submit(task).get()
: executor.submit(task).get(timeOut.toMillis(), TimeUnit.MILLISECONDS)) {
// business logic
} catch (SQLException e) {
// log
} catch (InterruptedException e) {
// log
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
// log
} catch (Exception e) {
// log
} finally {
executor.shutdownNow();
}
I have a piece of code which is supposed to fail if getConnection() takes too long,
I am new to combining resource management with concurrency, is there any risk of resource leak if I implement it like this?
Is there a better way to do it?

Related

Java: gRPC with FutureStub and ListenableFuture

I'm learning gRPC with Java and as an example I've defined three request types (cuboid, sphere and cylinder) and a single response type (String) where I put message about the calculated volume of a specific geometry. I followed this example, which use blocking stub on the client side and the program runs correctly. However, I want to try the asynchronous approach, so here is my client side code, written with newFutureStub and ListenableFuture:
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost",8080)
.usePlaintext()
.build();
GeometryServiceGrpc.GeometryServiceFutureStub stub = GeometryServiceGrpc.newFutureStub(channel);
ListenableFuture<Response> cuboidResp = stub.calcCuboidVol(CuboidVolumeRequest.newBuilder()
.setLength(2)
.setWidth(3)
.setHeight(4)
.build());
cuboidResp.addListener(() -> {
try {
System.out.println(cuboidResp.get().getResponse());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}, command -> {
command.run();
});
ListenableFuture<Response> sphereResp = stub.calcSphereVol(SphereVolumeRequest.newBuilder()
.setRadius(2)
.build());
sphereResp.addListener(() -> {
try {
System.out.println(sphereResp.get().getResponse());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}, command -> {
command.run();
});
ListenableFuture<Response> cylinderResp = stub.calcCylinderVol(CylinderVolumeRequest.newBuilder()
.setRadius(2)
.setHeight(3)
.build());
cylinderResp.addListener(() -> {
try {
System.out.println(cylinderResp.get().getResponse());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}, command -> {
command.run();
});
channel.shutdown();
}
Since we must use ListenableFuture I attach its method addListener() to each return instance of a specific geometry method (the Response message has a single string field called response). Basically, the desired result is just to print the calculations once they're ready and that's why a System.out.println is called in the runnable part. Although the program gets executed successfully, nothing is printed. But if check a specific geometry, then all results appear to the console. Example:
if(!cylinderResp.isDone()) {
try {
cylinderResp.get().getResponse();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
Does this means that the program terminates before the asynchronous part is completed? And is the executable part (commnad) written correctly (I searched and found out that this part can be executed by a ExecutorService if we want the code to be run on different thread(s) - not a requirement in my case)?
Does this means that the program terminates before the asynchronous part is completed? Yes, that's right, you should wait it execute complete by call cylinderResp.get() or channel.awaitTermination(5, TimeUnit.SECONDS);
And is the executable part (commnad) written correctly, If you want run task in specify thread pool you should add a ExecutorService, or it will executed by default thread pool.
For completely asynchronous you should use StreamObserver.
For more detail of how to use gRPC in Java you can reference my code helloworlde/grpc-java-sample

Is there a limit for exceptions fireable at runtime in java?

I have a method, basically a loop (with all the proper catch conditions) where the exit condition is the frame being closed. This method that does something that needs an internet connection. If there isn't an internet connection it will recursively call itself until the internet connection is restored. I have noticed that after a certain amount of exceptions fired, it will simply stop to call recursively the method and therefore and no exceptions are fired after that. Is there a limit for exceptions fireable at runtime?
public Download()
{
try {
while(!frame.isWindowClosed())
{
//doSomething
}
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
textArea.append("****** FailingHttpStatusCodeException ******\n");
new Download();
} catch (MalformedURLException e) {
e.printStackTrace();
textArea.append("****** MalformedURLException ******\n");
new Download();
} catch (IOException e) {
e.printStackTrace();
textArea.append("****** IOException ******\n");
new Download();
} catch (Exception e) {
e.printStackTrace();
textArea.append("****** Exception ******\n");
new Download();
}
}
set the try inside the loop so as long as the frame is not closed, the loop will continue. If the catch block is the same for all your Exceptions you can just catch the highest Exception:
public Download() {
while (!frame.isWindowClosed()) {
try {
// doSomething
} catch (Exception e) {
e.printStackTrace();
textArea.append("****** "+e.getClass().getName()+" ******\n");
}
}
}
As long as doSomething() did not succeeded in closing the frame the while loop will retry.
I think it's better for you to have that loop inside a method that is not inside the constructor.. Then call the method from the constructor.
I think what you should be doing is having a mechanism to check if there is network connectivity.. Then perform the required operation if there is connection. If there is no internet connectivity, then continue. You'll have to wrap this inside a while loop of course

throw exception from java task does not work

I am trying to throw an exception inside a task which is run on a separate thread. Then I want to catch the exception on the calling thread. See my trial below:
When I run the code now it hangs at the line with "throws new RuntimeException.."
Task calcTask = createCalcTask();
ExecutorService executor = Executors.newFixedThreadPool(1);
Future future = executor.submit(calcTask);
try {
future.get();
} catch (ExecutionException ex) {
ex.getCause().printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
public Task<Object> createCalcTask() {
return new Task<Object>() {
#Override
protected Object call() throws Exception {
throw new RuntimeException("testE");
}
};
}
try this....
line throwing exception should be inside try block
try {
Future future = executor.submit(calcTask); //
future.get();
} catch (ExecutionException ex) {
ex.printStackTrace();
}

Java ExecutorService REST call error

I am trying to use Java's ExecutorService to send out concurrent REST requests which make various logs of system information (coming from a controller), however am running into a bug. About half of my requests successfully make it to the target, but the other half appear as if they are sent, but are not found on the server they were sent to. I think I may have a flaw in the logic of setting up my ExecutorService. The function log() shown below can be called from a REST call to the controller, and is supposed to create a new thread which sends out a separate HTTP request, and continue with the main thread so as not to wait for the network I/O. After much searching, I believe I have the ExecutorService shutdown properly an wait for the thread to complete. Can anybody see some type of error in the logic of my thread creation, as multiple requests from the controller can continue to come in?
//Controller
//code
#RequestMapping(value="/log", method= RequestMethod.GET)
public String log()
{
genomicsLogger.log(Severity.err, Category.LOG, "This is a log from the reporting manager!");
return "Hopefully logged";
}
//ClassB
public String log(String trns , String user, Severity severity, Category category, String msg) {
trnsField = trns;
userField = user;
...
...
...
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable task = () -> {
try {
System.out.println("Started thread: " + Thread.currentThread().getName());
restService.consumeRest(true, instance.getUri().toString(), LOG_URI, list, log, HttpMethod.POST, new HttpHeaders(), String.class);
System.out.println("SENT REST REQUEST");
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
};
executor.submit(task);
try {
System.out.println("attempt to shutdown executor");
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
System.err.println("tasks interrupted");
}
finally {
if (!executor.isTerminated()) {
System.err.println("cancel non-finished tasks");
}
executor.shutdownNow();
System.out.println("shutdown finished");
}
return "";
}
You are creating executor service with each log and killing it.
This is not the way to use it, it is meant to be reused, make it e.g. a field in this class and set some number of threads that you are willing to use for it (probably higher than 1). And don't do shutdown on it until you are really sure it won't be used (e.g. during application shutdown).

How to deal with timeout exception in Java?

Here is my code:
private void synCampaign() {
List<Campaign> campaigns;
try {
campaigns = AdwordsCampaign.getAllCampaign();
for(Campaign c : campaigns)
CampaignDao.save(c);
} catch (ApiException e) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synCampaign();
e.printStackTrace();
} catch (RemoteException e) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synCampaign();
e.printStackTrace();
}
}
AdwordsCampaign.getAllCampaign() tries to get some remote resource. This may throw a RemoteException because the internet connection times out. When the exception is caught, I just want the thread to sleep for a while, then try to get the remote resource again.
Is there a problem with my code? Or is there a better way?
Nothing really wrong, but the (potentially infinite) retry loop with recursion (and the stack growing) makes me a little nervous. I'd write instead:
private void synCampaignWithRetries(int ntries, int msecsRetry) {
while(ntries-- >=0 ) {
try {
synCampaign();
return; // no exception? success
}
catch (ApiException e ) {
// log exception?
}
catch (RemoteException e ) {
// log exception?
}
try {
Thread.sleep(msecsRetry);
} catch (InterruptedException e1) {
// log exception?
}
}
// no success , even with ntries - log?
}
private void synCampaign() throws ApiException ,RemoteException {
List<Campaign> campaigns = AdwordsCampaign.getAllCampaign();
for(Campaign c : campaigns)
CampaignDao.save(c);
}
This looks OK except the repetition of code in catch block(be sure of number of retries you want). You may want to create a private method to handle your exception as below:
private void synCampaign() {
List<Campaign> campaigns;
try {
campaigns = AdwordsCampaign.getAllCampaign();
for(Campaign c : campaigns)
CampaignDao.save(c);
} catch (ApiException e) {
e.printStackTrace();
waitAndSync();
} catch (RemoteException e) {
e.printStackTrace();
waitAndSync();
}
}
private void waitAndSync(){
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synCampaign();
}
You indeed cannot catch it as a SocketTimeoutException. What is possible is to catch the RemoteException, retrieve it's cause and check if that's an instanceof SocketTimeoutException.
try{
// Your code that throws SocketTimeoutException
}catch (RemoteException e) {
if(e.getCause().getClass().equals(SocketTimeoutException.class)){
System.out.println("It is SocketTimeoutException");
// Do handling for socket exception
}else{
throw e;
}
}catch (Exception e) {
// Handling other exception. If necessary
}

Categories