Judah Flynn Judah Flynn - 3 months ago 44
Java Question

ScheduledExecutorService shutdown not working with bufferedreader?

I am using Java 8. I have a thread need start at a specific time and end at a specific time. I am using

to do the job:

I have two threads one name is "worker" and the other is "stopworker". The
Worker
class contains the actual code I need run at the specific time, the "stopworker" thread just shuts down the scheduler.

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.schedule(worker, startSeconds, TimeUnit.SECONDS);
scheduler.schedule(stopWorker, endSeconds, TimeUnit.SECONDS);


My
Worker
class:

class Worker implements Runnable {
@Override
public void run() {
try {
// HTTP GET method to call and REST API and get Streaming
// data back, it will keep alive as long as possible and
// gets lots of data back
...
BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getStream()));
// deal with the data
...
} catch (IOException e) {

} finally {
reader.close();
}
}
}


My
StopWorker
class:

class StopWorker implements Runnable {
@Override
public void run() {
try {
scheduler.shutdownNow();
} catch (Exception e) {
e.printStackTrace();
}
}
}


My code can start at the time I want, however, it's not shutdown correctly. I have fiddle this code a little bit and found this is because the
BufferedReader
class I used.

If I replaced the "worker" thread into a simple thread sleep statement and my "stopworker" works! That's why I think I/O part might block my shutdown.

The only way I shutdown the thread is by making my
BufferedReader
variable global and close it manually in
StopWorker
class. However, the code will be ugly and an
IOException
will be throw in the code.

My guessing is the
shutdownNow
function is still waiting the I/O finish first, am I right? Is there a good way solve this elegantly? Or is there a better way to make a thread start at a specific time and end at a specific time?

Answer

schedule() returns a ScheduledFuture, which has a boolean cancel(boolean mayInterruptIfRunning) method. If the input stream is closable by thread interruption then just call it with true.

If the stream is not interruptible then you need to close it explicitly.

Comments