Can't restart thread [duplicate] - java

This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 7 years ago.
I have the following thread:
public void start() {
isRunning = true;
if (mainThread == null) {
mainThread = new Thread(this);
mainThread.setPriority(Thread.MAX_PRIORITY);
}
if (!mainThread.isAlive()) {
try {
mainThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
At some point I want to stop it's operation:
public void stop() {
isRunning = false;
System.gc();
}
When calling start() again the following exception is thrown:
java.lang.IllegalThreadStateException
Pointing the mainThread.start() line of code.
What is the best way to start/stop a thread? how can I make this thread reusable?
Thanks!

Once a thread stop you cannot restart it in Java, but of course you can create a new thread in Java to do your new job.
The user experience won't differ even if you create a new thread or restart the same thread(this you cannot do in Java).
You can read the website for API specification http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html
What you might be looking for is Interrupts. An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
To know more about interrupts read the Java tutorial guide http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

From your code slice it seems that you are using a Runnable class with a Thread attribute. Instead of using stop/start you might use suspend/resume below:
private boolean isPaused;
public void run() {
while (!isRunning) {
// do your stuff
while (isPaused) {
mainThread.wait();
}
}
}
public void suspend() {
isPaused = true;
}
public void resume() {
isPaused = false;
mainThread.notify();
}
I did not add the synchronized blocks to keep the code small, but you will need to add them.

Related

Check if another Thread is interrupted, without polling

I'd like to check to see if a Thread is Interrupted, from some other Thread, without polling this to check - i.e. some kind of monitor.
Specifically, what I am trying to do is force-kill (Stop) a Thread when it is Interrupted. I will include a code example below of a trivial example of what I have done so far - it works, but polling to check if the Thread is interrupted is sub-optimal and I would like to avoid this.
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
#Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
I can't recommend strongly enough that you don't use Thread#stop().
It should never have existed, was deprecated very quickly and frankly should have been removed about 20 years ago.
You have no idea what the thread is doing when you stop it and it is very easy to corrupt shared objects and leave external resources (e.g. files) in an invalid state.
Suppose the thread is in the middle of resizing a shared ArrayList<> there's risk the object will be corrupted and your whole program fails intermittently in ways you cannot fix.
Do not use Thread#stop() it is broken and cannot be fixed.
It's a terrible feature of Java that it leads people into invalid techniques regarding threads.
Caveat over - how about just overriding interrupt() in a sub-class?
public void interrupt(){
this.stop();
}
You've decided to sub-class Thread (rather than Runnable) so this will "work". "work" in the sense of what you're doing. Not actually work or anything.
The only valid way to solve this is have the thread you want to terminate co-operate by responding to interrupt() as an instruction to come to a suitable point and then terminate cleanly.
Or you can create another flag indicating the thread should end.
I don't know why you need to monitor the thread externally. But here is a small sample how you could do it if you really need it:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
#Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
Now just use it like this:
MonitoredThread mt = new MonitoredThread() {
#Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());

Interrupting unknown thread

Consider the following (simplified) class, designed to allow my entire component to enter some interim state before completely stopping. (The purpose of the interim state is to allow the component to complete its existing tasks, but reject any new ones).
The component might be started and stopped multiple times from any number of threads.
class StopHandler {
boolean isStarted = false;
synchronized void start() {isStarted = true;}
//synchronized as I do want the client code to block until the component is stopped.
//I might add some async method as well, but let's concentrate on the sync version only.
synchronized void stop(boolean isUrgent) {
if (isStarted) {
if (!isUrgent) {
setGlobalState(PREPARING_TO_STOP); //assume it is implemented
try {Thread.sleep(10_000L);} catch (InterruptedException ignored) {}
}
isStarted = false;
}
}
The problem with the current implementation is that if some client code needs to urgently stop the component while it is in the interim state, it will still have to wait.
For example:
//one thread
stopHandler.stop(false); //not urgent => it is sleeping
//another thread, after 1 millisecond:
stopHandler.stop(true); //it's urgent, "please stop now", but it will wait for 10 seconds
How would you implement it?
I might need to interrupt the sleeping thread, but I don't have the sleeping thread object on which to call 'interrupt()'.
How about storing a reference to current Thread (returned by Thread.currentThread()) in a field of StopHandler directly before you call sleep? That would allow you you to interrupt it in the subsequent urgent call in case the Thread is still alive.
Couldn't find a better solution than the one suggested by Lars.
Just need to encapsulate the sleep management for completeness.
class SleepHandler {
private final ReentrantLock sleepingThreadLock;
private volatile Thread sleepingThread;
SleepHandler() {
sleepingThreadLock = new ReentrantLock();
}
void sleep(long millis) throws InterruptedException {
setSleepingThread(Thread.currentThread());
Thread.sleep(millis);
setSleepingThread(null);
}
void interruptIfSleeping() {
doWithinSleepingThreadLock(() -> {
if (sleepingThread != null) {
sleepingThread.interrupt();
}
});
}
private void setSleepingThread(#Nullable Thread sleepingThread) {
doWithinSleepingThreadLock(() -> this.sleepingThread = sleepingThread);
}
private void doWithinSleepingThreadLock(Runnable runnable) {
sleepingThreadLock.lock();
try {
runnable.run();
} finally {
sleepingThreadLock.unlock();
}
}
}
With this helper class, handling of the original problem is trivial:
void stop(boolean isUrgent) throws InterruptedException {
if (isUrgent) {sleepHandler.interruptIfSleeping();} //harmless if not sleeping
try {
doStop(isUrgent); //all the stuff in the original 'stop(...)' method
} catch (InteruptedException ignored) {
} finally {
Thread.interrupted(); //just in case, clearing the 'interrupt' flag as no need to propagate it futher
}

How to stop execution of method called from run() method of thread

Here is my Thread:-
Thread t=new Thread(){
public void run(){
downloadFile();
}
}
t.start();
public static void main(){
t.interrupt();
}
Here downloadFile() is long running method (downloading file from server)
The issue is , even though t.interrupt() is called downloadFile() method still keeps running which is not expected . I want downloadFile() method to terminate immediately as soon as the thread is interrupted. How should i achieve it ?
Thanks.
EDIT1:
Here is downloadFile() skeleton which calls the rest API to fetch file:
void downloadFile(){
String url="https//:fileserver/getFile"
//code to getFile method
}
Your Runnable needs to store an AtomicBoolean flag to say whether it has been interrupted or not.
The interrupt method should just set the flag to true.
The downloadFile() method needs to check the flag inside the download loop and abort the download if it is set.
Something like this is the only clean way to implement it as only downloadFile knows how to safely and cleanly interrupt itself, closing sockets etc.
You need some flag to inform a thread about termination:
public class FileDownloader implements Runnable {
private volatile boolean running = true;
public void terminate() {
running = false;
}
#Override
public void run() {
while (running) {
try {
downloadFile();
} catch (InterruptedException e) {
running = false;
}
}
}
}
in main:
FileDownloader fileDownloaderRunnable = new FileDownloader();
Thread thread = new Thread(fileDownloaderRunnable);
thread.start();
//terminating thread
fileDownloaderRunnable.terminate();
thread.join();

Thread termination using interrupt method

I have a thread which runs a task of file parsing. Its set as a daemon thread which runs in background from tomcat startup to shutdown doing its task.
I am looking to handle thread termination upon interruption and server shutdown. I want to know if am going about correctly.
class LoadingModule{ // Thread is started from here
threadsStartMethod() {
Thread t = new Thread(FileParseTask);
t.setDaemon(true);
t.start();
}
}
Class FileParseTask implements Runnable {
#Override
public void run() {
try {
while(!Thread.currentThread.isInterrupted) {
// poll for file creation
// parse and store
}
} catch(Exception exit) {
log.error(message);
Thread.currentThread.interrupt();
}
}
}
would this cleanly exit the thread in all scenarios?
it would depend on the code inside the loop. If the code inside the loop captures the interrupted exception and recovers, you will never see it. Also generic exception "exit" hides other exceptions. Change the code so you know what hit you.
I would do the following
Class FileParseTask implements Runnable {
#Override
public void run() {
while(!Thread.currentThread.isInterrupted) {
try {
// poll for file creation
// parse and store
} catch(Exception exit) {
if (InterruptedException)
break;
else{
//
}
log.error(message);
}
}
}
}
This has worked for me with up to 2K threads with no problems

Running many thread and Stop thread on Exception

I have a Thread (implements Runnable) from many branch officer call that thread with their branch code. I set up a name of their thread with branch code.
The problems are...
When an exception occurred in running thread - I can't stop that. And when try to make another thread with any name "ExceptionInInitializerError" or "OutOfMemoryError: Java heap space" comes
"OutOfMemoryError: Java heap space" exception comes When 2 or more thread running at a time.
public MyRunnerClass {
//This method called from many branch with their branch Code
public void executeBranchProcess(String branchCode){
Thread t = new Thread(new Exporter(branchCode);
t.setName(branchCode);
t.start();
}
}
Thread Class here
public class Exporter implements Runnable{
private String branchCode;
public Exporter(String branchCode){
this.branchCode = branchCode;
}
#Override
public void run() {
try {
exportCorner();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void exportCorner() throws InterruptedException{
try{
//Some Process
}catch(Exception e){
// I want to close running thread here
// I am using closeThread(this.branchCode), but not working
}
}
static void closeThread(String branchCode) throws InterruptedException {
Thread thread = null;
for (Thread t : Thread.getAllStackTraces().keySet()) {
if (t.getName().equals(branchCode))
thread = t;
}
if (thread != null) {
thread.interrupt();
thread.join();
}
}
}
You face multiple problems here:
You cannot join a thread in itself. Thread.join() waits until the thread dies. But if you call it from the thread you want to stop, it just waits forever.
To stop a thread you simply have to return from its run() method. In your case, just add return in your catch clause instead of calling closeThread().
It seems that you have some memory problems. Either whatever you do in exportCorner() uses alot of memory or you create to many threads at once. As Andy Turner has mentioned in the comments, it might be usefull to use an ExecutorService to handle your Runnables. This may help you managing your threads and ensure a limited thread count.

Categories

Resources