shutdown threads using managedexecutorservice after stipulated time - java

I have a list of threads that need to be executed simultaneously. I was doing this using executorservice initially. The threads that need to be executed are coming from DB and I am retrieving their classnames, storing them in vendorDetails list.
for (Object vendorThread : vendorDetails) {
String thread = (String) vendorThread;
//timeout = details.getTimeout();
Runnable worker = null;
try {
Class c = Class.forName(thread);
Constructor<?> cons = c.getConstructor(SearchRequest.class, Results.class);
worker = (Runnable) cons.newInstance(searchRequest, Results);
} catch (Exception e) {
//e.printStackTrace();
}
if (worker == null) {
System.out.println("------------------------ WORKER IS NULL ---------------");
}
executor.execute(worker);
}
executor.shutdownNow();
try {
if (!executor.isTerminated()) {
executor.awaitTermination(timeout, TimeUnit.SECONDS);
}
} catch (InterruptedException ex) {
//ex.fillInStackTrace();
}
I want to achieve something similar in ejb so I am using ManagedExecutorService.
#EJB
private ThreadName1 threadName1 ;
#EJB
private ThreadName2 threadName2 ;
for (Object vendorThread : vendorDetails) {
System.out.println("in for loop");
String thread = (String) vendorThread;
System.out.println("thread:" + thread);
//timeout = details.getTimeout();
Runnable worker = null;
try {
if (thread.equals("threadName1")) {
System.out.println("in if");
threadName1.setReqRes(SearchRequest, Results);
worker = (Runnable) threadName1;
} else if (thread.equals("threadName2")) {
System.out.println("in spice if");
threadName2.setReqRes(SearchRequest, Results);
worker = (Runnable) threadName2;
}
System.out.println("after if");
} catch (Exception e) {
e.printStackTrace();
}
if (worker == null) {
System.out.println("------------------------ WORKER IS NULL ---------------");
}
System.out.println("before execute");
//managedExecutorService.execute(worker);
managedExecutorService.submit(worker);
System.out.println("after execute");
}
System.out.println("before shutdown");
//managedExecutorService.shutdownNow();
System.out.println("after shutdown");
try {
System.out.println("after shutdown");
/*if (!managedExecutorService.isTerminated()) {
managedExecutorService.awaitTermination(timeout, TimeUnit.SECONDS);
}*/
} catch (InterruptedException ex) {
ex.fillInStackTrace();
// ex.printStackTrace();
}
So ideally I want the threads to run for a stipulated time say 30secs and then return the results of whichever threads have completed their execution.
Now the problem is calling any threadlifecycle methods like shutdown etc throws an exception.
How do I achieve this?
I am using the default ManagedExecutorSerivce.

I dont know if this is the right solution. But I am doing this for now as a workaround. Adding to a Future list all the tasks that are submitted. Then waiting for stipulated time and cancelling all the running tasks. I am sure there is a more elegant solution.
ArrayList<Future> taskList = new ArrayList<>();
for (Object vendorThread : vendorDetails) {
System.out.println("in for loop");
String thread = (String) vendorThread;
System.out.println("thread:" + thread);
//timeout = details.getTimeout();
Runnable worker = null;
try {
if (thread.equals("threadName1")) {
System.out.println("in if");
threadName1.setReqRes(SearchRequest, Results);
worker = (Runnable) threadName1;
} else if (thread.equals("threadName2")) {
System.out.println("in spice if");
threadName2.setReqRes(SearchRequest, Results);
worker = (Runnable) threadName2;
}
System.out.println("after if");
} catch (Exception e) {
e.printStackTrace();
}
if (worker == null) {
System.out.println("------------------------ WORKER IS NULL ---------------");
}
System.out.println("before execute");
//managedExecutorService.execute(worker);
taskList.add(managedExecutorService.submit(worker));;
System.out.println("after execute");
}
System.out.println("before shutdown");
//managedExecutorService.shutdownNow();
System.out.println("after shutdown");
try {
System.out.println("after shutdown");
/*if (!managedExecutorService.isTerminated()) {
managedExecutorService.awaitTermination(timeout, TimeUnit.SECONDS);
}*/
System.out.println("before sleep");
long startTimeLogon = System.currentTimeMillis();
boolean allComplete;
int trueCount = 0;
while (true) {
System.out.println("true count " + trueCount++);
if ((System.currentTimeMillis() - startTimeLogon) >= timeout * 1000) {
break;
}
allComplete = true;
for (Future f : taskList) {
if (!f.isDone()) {
allComplete=false;
}
}
if(allComplete)
break;
Thread.sleep(250);
}
System.out.println("after sleep");
for (Future f : taskList) {
if (!f.isDone()) {
f.cancel(true);
}
}
System.out.println("after cancel");
} catch (InterruptedException ex) {
ex.fillInStackTrace();
// ex.printStackTrace();
}

Related

How to wait until for few callable tasks complete and then execute

I want to execute some processors in two threads.. few of them are independent and could run anytime but few of them have dependency.. whenver order of execution reaches to that processor i want to check whether all previous callable tasks are executed or not? and future should be executed once this current execute.
following is the main thread method
PackageExportGraph executeMultiThread(PackageExportGraph exportGraphInp, PackageExportContext exportContextnInp)
throws WTException {
Map<PackageExportDependencyProcessor, Boolean> processorToParallelExecutionMap = new LinkedHashMap<>();
this.processorQueue = new LinkedBlockingQueue<>();
ExecutorService execService = null;
try {
int threads = 2;// 2
countDownLatch = new CountDownLatch(threads);
execService = ExecutorServiceFactory.getDefault().newExecutorService(threads, true);
boolean isThread1Started = false;
ThreadedDepProcessor thread1 = new ThreadedDepProcessor(
exportGraphInp, countDownLatch,
processorToParallelExecutionMap, processorQueue, exportContextnInp, isThread1Started);
threadList.add(thread1);
thread1.addListener(this);
boolean isThread2Started = false;
ThreadedDepProcessor thread2 = new ThreadedDepProcessor(
exportGraphInp, countDownLatch,
processorToParallelExecutionMap, processorQueue, exportContextnInp, isThread2Started);
threadList.add(thread2);
thread1.addListener(this);
List<Future<LinkedBlockingQueue>> futureList = new ArrayList<>();
for (ThreadedDepProcessor thread : threadList) {
Future f = execService.submit(thread);
System.out.println("f " + f);
futureList.add(f);
}
int currentidx = 0;
for (PackageExportDependencyProcessor processor : origOrderedList) {
if (!processorToParallelExecutionMap.containsKey(processor)) {
System.out.println(" parallel threadStatusMap values 1 - " + threadStatusMap.values());
System.out.println("Adding parallel - " + processor);
if (currentidx > 0) {
while (threadStatusMap.containsValue(false)) {
System.out.println("Waiting");
System.out.println("threadStatusMap values - " + threadStatusMap.values());
Thread.sleep(1000);
}
Thread.sleep(2000);
// execService.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("Size - " + futureList.size());
for (Future f : futureList) {
System.out.println("futureList is done " + f.isDone());
System.out.println("Getting future Object");
if (f.isDone()) {
continue;
}
Object o = f.get(10, TimeUnit.SECONDS);
System.out.println(o);
/*
* Object object = f.get(10, TimeUnit.SECONDS); System.out.println("Obj " + object);
*/
}
processorQueue.put(processor);
Thread.sleep(2000);
}
else {
processorQueue.put(processor);
Thread.sleep(2000);
System.out.println("Size - " + futureList.size());
for (Future f : futureList) {
System.out.println("futureList is done " + f.isDone());
System.out.println("Getting future Object");
if (f.isDone()) {
continue;
}
Object o = f.get(10, TimeUnit.SECONDS);
System.out.println(o);
/*
* Object object = f.get(10, TimeUnit.SECONDS); System.out.println("Obj " + object);
*/
}
// execService.awaitTermination(5, TimeUnit.SECONDS);
while (threadStatusMap.containsValue(false)) {
System.out.println("Waiting");
System.out.println("threadStatusMap values - " + threadStatusMap.values());
Thread.sleep(1000);
}
}
for (ThreadedDepProcessor thread : threadList) {
System.out.println("Finished adding dependents" + thread.finishedAddingDependents.get());
}
}
else {
System.out.println("Adding non-parallel - " + processor);
processorQueue.put(processor);
}
currentidx++;
}
} catch (WTException | RuntimeException exc) {
if (Objects.nonNull(execService)) {
execService.shutdown();
}
throw exc;
} catch (Exception exc) {
throw new WTException(exc);
} finally {
System.out.println("shutting down");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
execService.shutdown();
}
return exportGraphInp;
}
and this is callable
#Override
public LinkedBlockingQueue call() throws WTException, InterruptedException {
try {
System.out.println("Started - ");
isThreadStarted = true;
while (!processorQueue.isEmpty()) {
nextEligible = processorQueue.take();
if (Objects.isNull(nextEligible)) {
finishedAddingDependents.set(true);
break;
}
System.out.println("calling addDependentObjects for processor - " + nextEligible);
nextEligible.addDependentObjects(exportGraph, exportContext);
nextEligible = null;
// notifyListeners();
}
} catch (Exception e) {
System.out.println("Error occured " + e);
e.printStackTrace();
return processorQueue;
} finally {
countDownLatch.countDown();
System.out.println("countDownLatch now - " + countDownLatch.getCount());
}
return processorQueue;
}
}
I was trying to check while(future.isDone()) but its going indefinite loop.
i want to check whether thread/callable execution is started or not.
If started then while executing serial processor i want to wait till all existing is executed and then start execution and wait till its execution do not pick next one
What i did is manitained one synchronized collection, which will let us know status of execution of each processor, and based on that we can wait or go ahead

Do my code may casuse memory leak or too many udp link?

I want to use snmp method to query some data by mutithread in sometime,if over time,then the task will be cancel,I write the code like this, if there is something wrong with my code(It means that the thread may only do step 1and step 2,but do not do the step 4:close snmp connetction),how to fix ?Can I have the method that is the task is cancel,I can still close the snmp clent at step 4?
public static void main(String[] args) throws InterruptedException {
var pool = new ThreadPoolExecutor(
100, 100, 0L, TimeUnit.NANOSECONDS, new LinkedBlockingQueue<>(100));
System.out.println("Executing first batch of tasks...");
submitTasks(pool);
System.out.println("Finish first batch of tasks...");
//call submitTasks(pool) many times
...
}
private static void submitTasks(ExecutorService executor) throws InterruptedException {
var tasks = new ArrayList<Callable<String>>(100);
for (int i = 0; i < 100; i++) {
tasks.add(() -> {
try {
//1.create snmp client
//2.query data with udp link
//3.return result
return result;
}catch (Exception ex){
log.error(String.valueOf(ex));
}
} finally {
//4.close snmp
if (snmp != null) {
snmp.close();
}
}
});
}
List<Future<String>> futureList=executor.invokeAll(tasks,1,TimeUnit.SECONDS);
List<String> list=new ArrayList<>();
for (int i = 0; i < futureList.size(); i++) {
Future<String> future = futureList.get(i);
try {
list.add(future.get());
} catch (CancellationException e) {
log.info("timeOut Task:{}", i);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
I have change the code from Alexander Pavlov's example,it seems that if the task is cancel,the finally code will never run.
public static void main(String[] args) throws InterruptedException {
var pool = new ThreadPoolExecutor(
3, 3, 0L, TimeUnit.NANOSECONDS, new LinkedBlockingQueue<>(1));
try {
System.out.println("Executing first batch of tasks...");
submitTasks(pool);
System.out.println("Executing second batch of tasks...");
} finally {
pool.shutdown();
}
}
private static void submitTasks(ExecutorService executor) throws InterruptedException {
var tasks = new ArrayList<Callable<String>>(3);
final var latch = new CountDownLatch(3);
log.info(String.valueOf(latch.getCount()));
for (int i = 0; i < 3; i++) {
tasks.add(() -> {
try {
String s="1";
log.info("this.name:"+Thread.currentThread().getName());
for(int a=0;a<1000000L;a++) {
s=a+"";
}
return s;
}catch (Exception ex){
log.error(String.valueOf(ex));
}finally {
latch.countDown();
}
return null;
});
}
List<Future<String>> futureList=executor.invokeAll(tasks,1,TimeUnit.NANOSECONDS);
List<String> list=new ArrayList<>();
//latch.await();//
for (int i = 0; i < futureList.size(); i++) {
Future<String> future = futureList.get(i);
try {
list.add(future.get());
} catch (CancellationException e) {
log.info("timeOut Task:{}", i);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
log.info(String.valueOf(latch.getCount()));
log.info("start to await:");
try {
latch.await(); // WAIT UNTIL ALL TASKS ARE REALLY DONE
} catch (InterruptedException ex) {
log.error(String.valueOf(ex));
}
//never log end to await
log.info("end to await:");
log.info(String.valueOf(latch.getCount()));
}
invokeAll with timeout just calls Thread.interrupt() for running tasks. It does not wait until task stops, it notifies task that interruption is requested. Moreover, some tasks may ignore interruption and continue working. So when you are returning from submitTasks then it does not mean all underlying tasks are really stopped.
If you want to be 100% sure that all tasks are stopped when you exit from submitTasks then use CountDownLatch to control how many tasks have been really finished and exit when running tasks count is zero.
private static void submitTasks(ExecutorService executor) throws InterruptedException {
var c = 100;
final var latch = new CountDownLatch(c); // EXPECT 100 TASKS TO BE COMPLETED
var tasks = new ArrayList<Callable<String>>(c);
for (int i = 0; i < c; i++) {
tasks.add(() -> {
try {
//1.create snmp client
//2.query data with udp link
//3.return result
return result;
} catch (Exception ex) {
log.error(String.valueOf(ex));
} finally {
//4.close snmp
if (snmp != null) {
snmp.close();
}
latch.countDown(); // 1 MORE TASK IS COMPLETED
}
});
}
List<Future<String>> futureList = executor.invokeAll(tasks, 1, TimeUnit.SECONDS);
List<String> list = new ArrayList<>();
for (int i = 0; i < futureList.size(); i++) {
Future<String> future = futureList.get(i);
try {
list.add(future.get());
} catch (CancellationException e) {
log.info("timeOut Task:{}", i);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
try {
latch.await(); // WAIT UNTIL ALL TASKS ARE REALLY DONE
} catch (InterruptedException ex) {
log.error(ex);
}
}

Executor service is gets stuck, Not throwing error

when i call the below method recursively it is getting stucked and not throwing error. not giving any response. thread pool size is 50. when processing 100K records i am facing this issue.
how to solve this?
Thanks in Advance
public void processActivityDeposits(
Activity activity) {
int partitionSize =
environment.getProperty("patition.size", Integer.class, 1000);
List<Long> records =
service.findReadyToProcessRecords(
activity.getActivityId(),
partitionSize);
if (records != null && records.size() > 0) {
try {
int threadPoolSize =
environment.getProperty("thread.pool.size", Integer.class, 10);
ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
for (Long activityId : records) {
executorService.execute(
new ActivityDepositInternalProcessor(
activityId));
}
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
processActivityDeposits(
activity);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
I would suggest following changes to your code.
a. move the execution service creation and shutdown out of the if block.
b. Do not set the thread pool size more than 5 as you have only one core,
public void processActivityDeposits(
Activity activity) {
int partitionSize =
environment.getProperty("patition.size", Integer.class, 1000);
List<Long> records =
service.findReadyToProcessRecords(
activity.getActivityId(),
partitionSize);
//moved out of if block
int threadPoolSize =
environment.getProperty("thread.pool.size", Integer.class, 10);
ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
if (records != null && records.size() > 0) {
try {
for (Long activityId : records) {
executorService.execute(
new ActivityDepositInternalProcessor(
activityId));
}
processActivityDeposits(
activity);
} catch (Exception exception) {
exception.printStackTrace();
}
}
//moved out of if block
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Multiple ExecutorCompletionService not working

I've a requirement to start and stop task from java application. I'm trying to use
ExecutorService to create threads and ExecutorCompletionService to check
processing status of thread . Startup and stop is a continious activity so in my
test code I've created a while loop .
public class ProcessController {
String[] processArray = { "Process1", "Process2", "Process3", "Process4", "Process5", "Process6", "Process7" };
private List<String> processList = Arrays.asList(processArray);
public static void main(String[] args ) {
ExecutorService startUpExecutor = Executors.newFixedThreadPool(3);
ExecutorService cleanUpExecutor = Executors.newFixedThreadPool(3);
CompletionService<String> startUpCompletionService = new ExecutorCompletionService<>(startUpExecutor);
CompletionService<String> cleanUpCompletionService = new ExecutorCompletionService<>(cleanUpExecutor);
List<Future<String>> cleanupFutures = new ArrayList<Future<String>>();
List<Future<String>> startupFutures = new ArrayList<Future<String>>();
ProcessController myApp = new ProcessController();
int i = 0;
while (i++ < 3) {
System.out.println("**********Starting Iteration " + i + "************* =====> ");
if (!cleanupFutures.isEmpty()) cleanupFutures.clear();
myApp.processList.forEach(process -> cleanupFutures.add(cleanUpCompletionService.submit(new CleanupTask(process))));
myApp.processList.forEach(process -> startupFutures.add(startUpCompletionService.submit(new StartupTask(process))));
for (Future<String> f : cleanupFutures) {
try {
String result = cleanUpCompletionService.take().get();
System.out.println("Result from Cleanup thread : " + result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
for (Future<String> f1 : startupFutures) {
try {
String result = startUpCompletionService.take().get();
System.out.println("Result from startup thread : " + result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("**********Finished Iteration " + i + "************* =====> ");
}
startUpExecutor.shutdown();
cleanUpExecutor.shutdown();
}
}
CleanupTask class
public class CleanupTask implements Callable<String> {
private String task;
public CleanupTask(String task) {
this.task = task;
}
#Override
public String call() throws Exception {
checkIfAnyFinished();
return "finished clean up processing for " + getThreadId();
}
private void checkIfAnyFinished( )
{
System.out.println( getThreadId() + " Checking if task " + this.task + " is finished");
try {
isFinished();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void isFinished() throws InterruptedException {
Thread.sleep(1000*4);
}
private String getThreadId()
{
return Thread.currentThread().getName();
}
}
Startup Task class
public class StartupTask implements Callable<String> {
private String processSchedule ;
public StartupTask(String processSchedule) {
this.processSchedule = processSchedule;
}
#Override
public String call() {
scheduleifdue();
return "finished start up up processing for " + getThreadId();
}
private void scheduleifdue()
{
System.out.println(getThreadId() + " Checking " + this.processSchedule + " is due or not");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private String getThreadId()
{
return Thread.currentThread().getName();
}
}
Above code successfully complete iteration 1 and start 2nd iteration . But it never finish and keeps running.
When I run the same application only with one task( either cleanup or startup) then it run without any issues. I'm not sure what is causing issue.

How to give message when Threadpool Executor is completed?

I am trying to give a pop up alert message when my ThreadpoolExecutor is finished executing. It is searching email addresses from websites, once it is done I want a alert message as "Completed". Here is my Thread :-
public class Constant
{
public static final int NUM_OF_THREAD = 60;
public static final int TIME_OUT = 10000;
}
ThreadPoolExecutor poolMainExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool
(Constant.NUM_OF_THREAD);
Here is my Searching Operation class :-
class SearchingOperation implements Runnable {
URL urldata;
int i;
Set<String> emailAddresses;
int level;
SearchingOperation(URL urldata, int i, Set<String> emailAddresses, int level) {
this.urldata = urldata;
this.i = i;
this.emailAddresses = emailAddresses;
this.level = level;
if (level != 1)
model.setValueAt(urldata.getProtocol() + "://" + urldata.getHost() + "/contacts", i, 3);
}
public void run() {
BufferedReader bufferreader1 = null;
InputStreamReader emailReader = null;
System.out.println(this.i + ":" + poolMainExecutor.getActiveCount() + ":" + level + ";" + urldata.toString());
try {
if (level < 1) {
String httpPatternString = "https?:\\/\\/(www\\.)?[-a-zA-Z0-9#:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9#:%_\\+.~#?&//=]*)";
String httpString = "";
BufferedReader bufferreaderHTTP = null;
InputStreamReader httpReader = null;
try {
httpReader = new InputStreamReader(urldata.openStream());
bufferreaderHTTP = new BufferedReader(httpReader
);
StringBuilder rawhttp = new StringBuilder();
while ((httpString = bufferreaderHTTP.readLine()) != null) {
rawhttp.append(httpString);
}
if (rawhttp.toString().isEmpty()) {
return;
}
List<String> urls = getURL(rawhttp.toString());
for (String url : urls) {
String fullUrl = getMatchRegex(url, httpPatternString);
if (fullUrl.isEmpty()) {
if (!url.startsWith("/")) {
url = "/" + url;
}
String address = urldata.getProtocol() + "://" + urldata.getHost() + url;
fullUrl = getMatchRegex(address, httpPatternString);
}
if (!addressWorked.contains(fullUrl) && fullUrl.contains(urldata.getHost())) {
addressWorked.add(fullUrl);
sendToSearch(fullUrl);
}
}
} catch (Exception e) {
//System.out.println("652" + e.getMessage());
//e.printStackTrace();
return;
} finally {
try {
if (httpReader != null)
bufferreaderHTTP.close();
} catch (Exception e) {
// e.printStackTrace();
}
try {
if (httpReader != null)
httpReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
String someString = "";
emailReader = new InputStreamReader(urldata.openStream());
bufferreader1 = new BufferedReader(
emailReader);
StringBuilder emailRaw = new StringBuilder();
while ((someString = bufferreader1.readLine()) != null) {
if (someString.contains("#")) {
emailRaw.append(someString).append(";");
}
}
//Set<String> emailAddresses = new HashSet<String>();
String emailAddress;
//Pattern pattern = Pattern
//.compile("\\b[a-zA-Z0-9.-]+#[a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+\\b");
Pattern
pattern = Pattern
.compile("\\b[a-zA-Z0-9.-]+#[a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+\\b");
Matcher matchs = pattern.matcher(emailRaw);
while (matchs.find()) {
emailAddress = (emailRaw.substring(matchs.start(),
matchs.end()));
// //System.out.println(emailAddress);
if (!emailAddresses.contains(emailAddress)) {
emailAddresses.add(emailAddress);
// //System.out.println(emailAddress);
if (!foundItem.get(i)) {
table.setValueAt("Found", i, 4);
foundItem.set(i, true);
}
String emails = !emailAddresses.isEmpty() ? emailAddresses.toString() : "";
model.setValueAt(emails, i, 2);
model.setValueAt("", i, 3);
}
}
} catch (Exception e) {
//System.out.println("687" + e.getMessage());
} finally {
try {
if (bufferreader1 != null)
bufferreader1.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (emailReader != null)
emailReader.close();
} catch (Exception e) {
e.printStackTrace();
}
Thread.currentThread().interrupt();
return;
}
}
After this the final snippet :-
private void sendToSearch(String address) throws Throwable {
SearchingOperation operation = new SearchingOperation(new URL(address), i,
emailAddresses, level + 1);
//operation.run();
try {
final Future handler = poolMainExecutor.submit(operation);
try {
handler.get(Constant.TIME_OUT, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
e.printStackTrace();
handler.cancel(false);
}
} catch (Exception e) {
//System.out.println("Time out for:" + address);
} catch (Error error) {
//System.out.println("Time out for:" + address);
} finally {
}
}
Implement Callable<Void> instead of Runnable and wait for all the task to terminate by calling Future<Void>.get():
class SearchingOperation implements Callable<Void>
{
public Void call() throws Exception
{
//same code as in run()
}
}
//submit and wait until the task complete
Future<Void> future = poolMainExecutor.submit(new SearchingOperation()).get();
Use ThreadPoolExecutor.awaitTermination():
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
As in your code, you create your ThreadPoolExecutor first
ThreadPoolExecutor poolMainExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Constant.NUM_OF_THREAD);
Then, you need to add Tasks to it:
poolMainExecutor.execute(myTask);
poolMainExecutor.submit(myTask);
execute will return nothing, while submit will return a Future object. Tasks must implement Runnable or Callable. An object of SearchingOperation is a task for example. The thread pool will execute the tasks in parallel, but each task will be executed by one thread. That means to effectively use NUM_OF_THREAD Threads you need to add at least NUM_OF_THREAD Tasks.
(Optional) Once you got all jobs to work, shutdown your pool. This will prevent new tasks from being submitted. It won't affect running tasks.
poolMainExecutor.shutdown();
At the end, you need to wait for all Tasks to complete. The easiest way is by calling
poolMainExecutor.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
You should adjust the amount of time you want to wait for the tasks to finish before throwing an exception.
Now that the work is done, notify the user. A simple way is to call one of the Dialog presets from JOptionPane, like:
JOptionPane.showMessageDialog(null, "message", "title", JOptionPane.INFORMATION_MESSAGE);
It will popup a little window with title "title", the message "message", an "information" icon and a button to close it.
This code can be used., it will check whether the execution is completed in every 2.5 seconds.
do {
System.out.println("In Progress");
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (poolMainExecutor.getActiveCount() != 0);
System.out.println("Completed");

Categories