I am trying to execute a query with a jdbcTemplate using an executor object but for some reason the program doesn't go inside the jdbcTemplate.
ExecutorService executor = Executors.newFixedThreadPool(NUMBER_OF_CONCURRENT_THREADS);
executor.execute(new Runnable() {
#Override
public void run() {
inboundJdbcTemplate.query(selectQuery, new RowCallbackHandler() {
#Override
public void processRow(ResultSet rs) throws SQLException {//<-instruction pointer never goes to this line
try {
//buffer.put(buildDataPoint(rs, testPermutationId));
System.out.println(rs.getString(0));
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
});
try {
buffer.put(STOPPING_TOKEN);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Can anyone help me with this stupid bug?
I found a solution to the problem.
I needed a CompletionService in order to make sure that I know when the execution of the JdbcTemplate finishes.
{...
ExecutorService executor = Executors.newFixedThreadPool(NUMBER_OF_CONCURRENT_THREADS);
CompletionService<String> completionService = new ExecutorCompletionService (executor);
completionService.submit(new Runnable() {
#Override
public void run() {
inboundJdbcTemplate.query(selectQuery, new RowCallbackHandler() {
#Override
public void processRow(ResultSet rs) throws SQLException {
try {
buffer.put(buildDP(rs, Id));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "Success");
try{
Future<String> take1 = completionService.take();
String s = take1.get();
if(!"Success".equals(s)) throw new RuntimeException("Error Occured");
catch (InterruptedException | ExecutionException e) {
LOG.error(" Could not execute DataExtraction",e);}
executor.shutdown();
...}
Related
The code I want to achieve is as below:
StreamSupport.stream(jsonArray.spliterator(), true).forEach(s ->{
try {
//invoke other api and set timeout for its execution
}
catch(TimeoutException e) {
s.getAsJsonObject().addProperty("processStatus", "Failure");
}
});
Can anyone help me in achieving "invoke other api and set timeout for it's execution" case in the above snippet?
I don't think you can do that inside a stream, but you can wrap the execution in a Callable like so to achieve the same result:
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println(future.get(1, TimeUnit.SECONDS));
}catch (Exception e) {
future.cancel(true);
e.printStackTrace();
} finally {
executor.shutdownNow();
}
}
private static class Task implements Callable<String> {
#Override
public String call(){
IntStream.of(1,2,3,4,5,6,7,8,9).parallel().forEach(t -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
return "ok";
}
}
I am building TODO app with room database and MVVM.
So since I can't use ROOM in main thread,I searched for solutions and came across "Callable" which is just what I need!
Since I have more than 5 functions that make database calls, I wonder how I can use the same Callable code instead of writing it 5 times in different functions.
This is how I currently doing it:
public List<Task> getAllUnCompletedTasksAsList() {
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getAllUnCompletedTasksAsList();
}
};
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public List<Task> getCompletedTasksAsList() {
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getCompletedTasksAsList();
}
};
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public List<Task> getWeeklyTasksAsList() {
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getWeeklyTasksAsList();
}
};
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
I would love to hear your suggestions,Thank you !
You are instantiating an anonymous inner class. Do it once outside the methods and use the field instance of your Callable.
private Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getAllUnCompletedTasksAsList();
}
};
And (for example)
public List<Task> getAllUnCompletedTasksAsList() {
/*
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getAllUnCompletedTasksAsList();
}
};
*/
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(this.callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
Considering this code
class ReportSenderRunnable implements Runnable {
#Override
public void run() {
executeTasks();
}
private void executeTasks() {
try {
runTask1();
} catch (final InterruptedException e) {
logError(ReportStatus.COMPRESSING, e.getMessage());
reportStatus = ReportStatus.EXCEPTION_IN_COMPRESSION;
} catch (final IllegalStateException e) {
logError(ReportStatus.COMPRESSING, e.getMessage());
reportStatus = ReportStatus.EXCEPTION_IN_COMPRESSION;
}
try {
reportStatus = ReportStatus.SENDING;
runTask2();
} catch (final InterruptedException e) {
reportStatus = ReportStatus.EXCEPTION_IN_SENDING;
}
try {
reportStatus = ReportStatus.SUBMITTING_REPORT;
runTask3();
} catch (final InterruptedException e) {
reportStatus = ReportStatus.EXCEPTION_IN_SUBMITTING_REPORT;
}
System.out.println("Report Sender completed");
reportStatus = ReportStatus.DONE;
}
private void logError(final ReportStatus status, final String cause) {
LOGGER.error("{} - {}", status, cause);
}
}
This code is passed to ExecutorService to run.
private void submitJob() {
final ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new ReportSenderRunnable());
System.out.println("started Report Sender Job");
}
Assuming runTask1(), runTask2() and runTask3() are already tested somewhere else, How can I test this code?
I am so very confused because I am learning multi-threaded programming now
Thank you
you can try to test like this
public class TestMultiThread {
#Test
public void testThread(){
final ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new ReportSenderRunnable());
System.out.println("started Report Sender Job");
}
}
i am trying to write a method that pings my database every hour. In doing so I am having some difficulties in sleeping the Thread is it might not have been initialised
private void pingServer(){
final Thread serverPing = new Thread(new Runnable() {
#Override
public void run() {
Connection conn = null;
try {
conn = source.getConnection();
while(conn.isValid(3600)){
//no need to do anything as conn.isValid does the ping
serverPing.sleep(3600000);
}
} catch (SQLException | InterruptedException e) {}
finally{
closeConnection(conn);
}
}
});
serverPing.setDaemon(true);
serverPing.start();
}
How can i modify this code to initialise it correctly?
Thanks
To sleep, just use Thread.sleep(3600000);
Yet, you should use a ScheduledExecutorService for this kind of tasks:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
try(Connection conn = source.getConnection()){
if(!conn.isValid(3600)){
// do something if the connection is invalid
}
}
}
}, 0, 1, TimeUnit.HOURS);
Just use Thread.sleep(TIME_GAP); to sleep the current thread.
Example
while(conn.isValid(3600)){
try {
Thread.sleep(3600000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I realized my ThreadPoolExecutor with PriorityBlockingQueue like in this example:
https://stackoverflow.com/a/12722648/2206775
and wrote a test:
PriorityExecutor executorService = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(16);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 1);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 3);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("5");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 5);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("4");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 4);
executorService.shutdown();
try {
executorService.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
But in the end, I don't get 1 2 3 4 5, I get a random order of those numbers. Is there a problem with the test, or something else? And if first, how can it be tested correctly?
The priority is only taken into account if the pool is fully busy and you submit several new tasks. If you define your pool with only one thread, you should get the expected output. In your example, all tasks get executed concurrently and which one finishes first is somewhat random.
By the way the linked implementation has a problem and throws an exception if your queue is full and you submit new tasks.
See below a working example of what you are trying to achieve (I have overriden newTaskFor in a simplistic way, just to make it work - you might want to improve that part).
It prints: 1 2 3 4 5.
public class Test {
public static void main(String[] args) {
PriorityExecutor executorService = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(1);
executorService.submit(getRunnable("1"), 1);
executorService.submit(getRunnable("3"), 3);
executorService.submit(getRunnable("2"), 2);
executorService.submit(getRunnable("5"), 5);
executorService.submit(getRunnable("4"), 4);
executorService.shutdown();
try {
executorService.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static Runnable getRunnable(final String id) {
return new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(id);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
static class PriorityExecutor extends ThreadPoolExecutor {
public PriorityExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
//Utitlity method to create thread pool easily
public static ExecutorService newFixedThreadPool(int nThreads) {
return new PriorityExecutor(nThreads, nThreads, 0L,
TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>());
}
//Submit with New comparable task
public Future<?> submit(Runnable task, int priority) {
return super.submit(new ComparableFutureTask(task, null, priority));
}
//execute with New comparable task
public void execute(Runnable command, int priority) {
super.execute(new ComparableFutureTask(command, null, priority));
}
#Override
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return (RunnableFuture<T>) callable;
}
#Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return (RunnableFuture<T>) runnable;
}
}
static class ComparableFutureTask<T> extends FutureTask<T> implements Comparable<ComparableFutureTask<T>> {
volatile int priority = 0;
public ComparableFutureTask(Runnable runnable, T result, int priority) {
super(runnable, result);
this.priority = priority;
}
public ComparableFutureTask(Callable<T> callable, int priority) {
super(callable);
this.priority = priority;
}
#Override
public int compareTo(ComparableFutureTask<T> o) {
return Integer.valueOf(priority).compareTo(o.priority);
}
}
}
You have 16 threads and only 5 tasks, meaning all of them are being executed concurrently and the priority is actually irrelevant.
The priority only matters when there are tasks waiting to be executed.
To show this, if you set your example to only use 1 thread, you will get your expected output.