ExecutorService's awaitTermination and InterruptedException - java

In my code, I have an executor service running:
//these are global variables
def newXmlParser = new XmlParser()
def processedResponse
Someloop.each{
URL->
executorService.execute(new Runnable() {
public void run() {
someURLService(URL)
}
});
}
where
public void someURLService(URL){
def urlConnection = HttpURLConnection(URL)
def response = urlConnection.getInputStream()
parseResponse(response)
}
public synchronized void parseResponse(response){
//previously declared XmlParser
processedResponse = newXmlParser.parse(response)
}
I am trying to implement this, because I have code dependent on the results of all finished tasks of the ExecutorService:
How to wait for all threads to finish, using ExecutorService?
Someloop.each{
URL->
executorService.execute(new Runnable() {
public void run() {
someURLService(URL)
}
});
}
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
However, it doesn't wait until it's finished, but bypasses the 'awaitTermination' with an InterruptedException. It doesn't give me any message, localized message, or cause.
Does anybody have a solution to this problem? Let me know if you need more details.

Related

Stop a scheduled ScheduledExecutorService

ScheduledExecutorService is still running after calling its shutdown methos from class's shutdown method below.
I was not expecting to see perioudRun's call after shutdown
Running the method shutdown
Running the method periodicRun-
What should I do ensure, the schedule run is cancelled ?
class test {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
test() {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
funcA("periodicRun-");
}
}, 15, 15, TimeUnit.SECONDS);
}
private void funcA(String path) {
LOGGER.info("Running the method " + path)
}
public void shutdown() {
long startTimeMs = System.currentTimeMillis();
scheduler.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!scheduler.awaitTermination(initialTerminationSeconds, TimeUnit.SECONDS)) {
scheduler.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
scheduler.awaitTermination(retryTerminationSeconds,
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
scheduler.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
funcA("shutdown-");
}
}```
The code you provided does not compile. I made some corrections and some assumptions where it did not compile, and the following code works as expected, i.e. "periodicRun" is not printed after shutdown() is called:
class Test {
public static void main(String[] args) {
Test test = new Test();
test.test(); // CALL TEST METHOD
Thread t = new Thread(() -> {
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.shutdown(); // CALL SHUTDOWN METHOD
});
t.start();
}
private final int initialTerminationSeconds = 1;
private final int retryTerminationSeconds = 1;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
void test() {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
funcA("periodicRun-");
}
}, 15, 15, TimeUnit.SECONDS);
}
private void funcA(String path) {
System.out.println("Running the method " + path);
}
public void shutdown() {
long startTimeMs = System.currentTimeMillis();
scheduler.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!scheduler.awaitTermination(initialTerminationSeconds, TimeUnit.SECONDS)) {
scheduler.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
scheduler.awaitTermination(retryTerminationSeconds, TimeUnit.SECONDS);
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
scheduler.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
funcA("shutdown-");
}
}
As this code works as expected, the problem in your code is either somewhere else or the assumptions and corrections I made to your code are incorrect.

Releasing CountDownLatch only when I receive a callback in one of my Thread

When to invoke doneSignal.await() in this scenario??
My requirement is to wait the return call until callback is received.
I tried invoking it in other thread and also in main thread. But no luck, callback is never received thereby freezing the app and initially when I was not using the CountDownLatch getCall was returning null value immediately without waiting for the callback. Below is my code
public UserSubscriptions getDocument(final String uid) {
final UserSubscriptions[] userSubscriptions = new UserSubscriptions[1];
final CountDownLatch doneSignal = new CountDownLatch(1);
try {
Thread getCall = new Thread(new Runnable() {
#Override
public void run() {
try{
DocumentReference docRef = db.collection("xyz").document(uid);
docRef.get()
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
userSubscriptions[0] = null;
TimerLog.e("document retrieve failed");
doneSignal.countDown();
}
})
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
userSubscriptions[0] = documentSnapshot.toObject(UserSubscriptions.class);
TimerLog.e("document retrieved successfully " + userSubscriptions[0].toString());
doneSignal.countDown();
}
});
TimerLog.e("control exitted from run");
} finally {
TimerLog.e("Nads in finally");
}
}
});
getCall.start();
TimerLog.e("before");
doneSignal.await();
TimerLog.e("after");
} catch (InterruptedException e) {
TimerLog.e("exception in await "+e.getLocalizedMessage());
}
return userSubscriptions[0];
}
Console Output :
before
control exitted from run
in finally
This CountDownLatch did not work for me neither any mutual exclusive lock thing. The best way to do such type of thing where you are receiving a callback from server then you should not have that function return anything. Simple method is to have callback functionality.

Safe thread utilization

I am using single thread executor for long-running threads like this:
executor = Executors.newSingleThreadExecutor(THREAD_FACTORY);
executor.submit(new LongRunnable());
which checks a flag to be stopped:
private class LongRunnable implements Runnable {
#Override
public void run() {
while (isRunning.get()) {
try {
doSomething();
} catch (InterruptedException e) {
...
}
}
}
}
and whole execution is interrupted that way:
#Override
public void close() throws Exception {
isRunning.set(false);
executor.shutdownNow();
}
Still I can see some threads not gc-ed in profiler (while by logs, runnable they were executing has quit outermost while loop).
Question: does provided working with threads strategy memory-leak-free and thread-leak-free?
I am not able to see any issue with executor or shutDownNow. Probably you are looking at different threads in your profiler.
Try this program which is similar to the one in your question and you can see the thread is no longer there after successful shutdown.
public class ExecutorShutdownTest {
private static ExecutorService executor;
private static AtomicLong executorThreadId = new AtomicLong(0);
public static void main(String[] args) {
// get thread MX bean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// create an executor and start the task
executor = Executors.newSingleThreadExecutor(new TestThreadFactory());
LongRunnable runnable = new LongRunnable();
executor.submit(runnable);
// main thread: keep running for sometime
int count = 5;
while (count-- > 0) {
try {
Thread.sleep(1000);
System.out.println(String.valueOf(threadMXBean.getThreadInfo(executorThreadId.longValue())).replace("\r", "").replace(
"\n", ""));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// main thread: stop the task
try {
runnable.close();
System.out.println(String.valueOf(threadMXBean.getThreadInfo(executorThreadId.longValue())).replace("\r", "").replace("\n", ""));
} catch (Exception e) {
e.printStackTrace();
}
// main thread: run some more time to verify the executor thread no longer exists
count = 5;
while (count-- > 0) {
try {
Thread.sleep(1000);
System.out.println(String.valueOf(threadMXBean.getThreadInfo(executorThreadId.longValue())).replace("\r", "").replace("\n", ""));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class LongRunnable implements Runnable {
private volatile boolean isRunning = true;
#Override
public void run() {
while (isRunning) {
System.out.println("Running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//ignore
}
}
System.out.println("Stopped");
}
public void close() throws Exception {
System.out.println("Stopping");
isRunning = false;
executor.shutdownNow();
}
}
private static class TestThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
TestThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0) {
#Override protected void finalize() throws Throwable {
super.finalize();
// probably bad idea but lets see if it gets here
System.out.println("Executor thread removed from JVM");
}
};
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
executorThreadId.set(t.getId());
System.out.println("Executor thread created");
return t;
}
}
}
Here's a sample program using the single-thread Executor that manages to strand a thread so that the JVM can't shut down, but it only manages to do it by not calling shutdownNow:
import java.util.concurrent.*;
public class Exec {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new MyTask());
Thread.sleep(20000L);
// executor.shutdownNow();
int retryCount = 4;
while (!executor.isTerminated() && retryCount > 0) {
System.out.println("waiting for tasks to terminate");
Thread.sleep(500L);
retryCount -= 1;
}
}
}
class MyTask implements Runnable {
public void run() {
int count = 0;
try {
while (!Thread.currentThread().isInterrupted() && count < 10) {
Thread.sleep(1000L);
count += 1;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("all done");
}
}
The thread used by the executor has a separate life cycle from the task, this example shows how the task finishes but the thread goes on. Uncommenting the shutdownNow results in the executor's thread terminating. Otherwise the main thread sleeps for a while and exits, leaving the executor's thread hanging out, preventing the JVM from exiting.
My guess is that your close method isn't getting called and your executor never gets shut down. To get more useful answers please add a MVCE so that we can reproduce the problem.
Consider that with interruption there's no need to keep a reference to the Runnable to set the flag. As I read the question the task not finishing is not an issue here, but it would still be better to make the Runnable respond to interruption and lose the flag, just because having less things to keep track of is always an improvement.

Threads running at same time instance

I have a requirement threading where I need to initiate a thread which will run continuously doing some DB operations . A second thread will be present which needs to run for every 30 secs. The job of the second thread will be killing the first thread and start a new instance of the first thread.
I tried several ways to achieve this but I am not able to do the same.
public class ThreadMain {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException{
final CyclicBarrier gate = new CyclicBarrier(3);
Thread t1 = new Thread(){
public void run(){
try {
gate.await();
while(true)
{
System.out.println("Thread1");
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
Thread t2 = new Thread(){
public void run(){
try {
gate.await();
while(true)
{
System.out.println("Continiously running thread:-Thread2");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
t1.start();
t2.start();
This seems to work nicely:
// Thread that runs forever.
volatile static Thread forEverThread = null;
static class ForEver implements Runnable {
#Override
public void run() {
try {
while (true) {
Thread.sleep(1000);
System.out.println("For Ever!");
}
} catch (InterruptedException ex) {
// Just quit if I was interrupted.
}
}
}
// Stop the thread if it is running.
private static void stopForeverThread() throws InterruptedException {
// Skip if non-existent.
if (forEverThread != null) {
// Make sure no-one else is already doing it.
synchronized (forEverThread) {
// Still not null?
if (forEverThread != null) {
// Interrupt it.
forEverThread.interrupt();
// Wait for it to finish.
forEverThread.join();
// Clear it.
forEverThread = null;
}
}
}
}
private static void restartForeverThread() throws InterruptedException {
System.out.println("Restarting...");
// Stop it if it is running.
stopForeverThread();
// Start it again.
forEverThread = new Thread(new ForEver());
forEverThread.start();
System.out.println("Restarted");
}
public static void start() throws InterruptedException {
// Start it all up.
restartForeverThread();
// Timed event to restart it.
Timer restartTimer = new Timer(true);
restartTimer.scheduleAtFixedRate(
new TimerTask() {
#Override
public void run() {
try {
// Restart every few seconds.
restartForeverThread();
} catch (InterruptedException ex) {
// We were interrupted during restart - Log it.
}
}
// Every few seconds.
}, 0, 10 * 1000);
}
public static void main(String args[]) {
try {
// Start it all up.
start();
// Hang around for a while - to see what happens.
Thread.sleep(60 * 1000);
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
If your database task is interruptible (i.e. it reacts on thread interruption and hence can be cancelled by that), the best strategy is to use an ScheduledExecutorService for both, the database task itself and the restart task that runs periodically.
Note that task and thread are two different things: While a task is a piece of work that should be run, threads are the mechanism to do this in parallel.
static class DatabaseTask implements Runnable {
public void run() {
...
}
}
static class RestartTask implements Runnable {
private final ExecutorService executor;
private volatile Future<Void> future;
public RestartTask(ExecutorService executor) {
this.executor = executor;
}
public void run() {
if (future != null) {
future.cancel(true);
}
future = executor.submit(new DatabaseTask());
}
}
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new RestartTask(executor), 0, 30, TimeUnit.SECONDS);
Note that if your DatabaseTask is NOT sensitive to thread interruption and continues to perform database operations, the number of threads executing database tasks will grow continously - probably not what you want. So make sure, all blocking database operations are either interruptible, or terminate within a reasonable amount of time.

Thread.join() not working in Android?

I want to create long-running application for performing various tasks on different threads. Each task should have one-minute timeout. Here is my implementation:
runner = new Thread(new Runnable() {
#Override
public void run() { }
// some actions here
});
runner.start();
startJoin = System.currentTimeMillis();
runner.join(TIMEOUT);
stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT)
throw new TimeoutException("Timeout when reading the response from process");
In general case it is working and throwing TimeoutExceptions, but sometimes it is doing nothing after even few hours. So the questions is if Thread.join is reliable on Android?
I have an idea to use Thread.wait and notify instead of that, what is the better way in your opinion?
Refer below program.
public static void main(String[] args) throws InterruptedException {
long TIMEOUT=100;
Thread runner = new Thread(new Runnable() {
#Override
public void run() {
for(;;){
System.out.println("running ");
}
}
// some actions here
});
runner.start();
long startJoin = System.currentTimeMillis();
runner.join(TIMEOUT);
long stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT)
try {
throw new Exception("Timeout when reading the response from process");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Running Thread");
}
This program never ends that means your logic is incorrect.
Better to use TimerTask.
I prefer doing all time base task using Timer and TimerTask. Check the following code and probably this should be useful to you:
Timer t =new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
//The task you want to perform after the timeout period
}
}, TIMEOUT);
EDIT
I am giving a try at solving your problem. I am using the code written by #amicngh as my base code and have done some modifications to it. I presume that after the TIMEOUT period you want to close the running thread. Check the following code runs fine and the explanation that follows:
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
final long TIMEOUT=100;
final long startJoin = System.currentTimeMillis();
Thread runner = new Thread(new Runnable() {
long stopJoin;
#Override
public void run() {
try{
for(;;){
System.out.println("running ");
stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT){
throw new Exception();
}
}
}
catch (Exception e) {
// TODO: handle exception
}
}
// some actions here
});
runner.start();
synchronized (ThreadTest.class) {
ThreadTest.class.wait(TIMEOUT);
}
/*if ((stopJoin - startJoin) >= TIMEOUT)
try {
throw new Exception("Timeout when reading the response from process");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("Running Thread");
}
}
The Thread API description says that it is unsafe to destroy or stop (hence both these method has been deprecated) and one of the way to stop a thread is to throw an exception. Hence I am checking for the Timeout inside the runner thread. Now about making the Main thread wait it is done by the 2 lines of code which uses synchronized to synchronize the access to the thread.
Hope this code and explanation solves your problem.

Categories