Destroying a thread, having a never ending function int its run() method? - java

In my run() method of my Thread class, I am calling a never ending function.
I need the thread to run only for a specific duration.
Am not able to control the thread once its started, Is their any way to destroy it?
I have tried yield(), sleep(), etc...
PS - I cannot change the never ending function

From oracle Java Docs:
public void run(){
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
}
Your thread should check interrupted condition after each loop to see if it was interrupted. If you are calling a method that just does while(true){} then I am afraid there is no way interrupting it and stop() MUST never be called on a thread.
It is the programmers responsibility to make a long running method responsive to interrupts.

http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html answers all your questions.. particularly section What should I use instead of Thread.stop?
Hope it helps

This could be too much, but this is how I would solve it, if you do not want to mess with Interrupt.
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadTest test = new ThreadTest();
test.go();
}
void go() throws InterruptedException{
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new LongRunnable());
if(!service.awaitTermination(1000, TimeUnit.MILLISECONDS)){
System.out.println("Not finished within interval");
service.shutdownNow();
}
}
}
class LongRunnable implements Runnable {
public void run(){
try{
//Simultate some work
Thread.sleep(2000);
} catch(Exception e){
e.printStackTrace();
}
}
}
Basically you are wrapping your runnable in a ExecutorServie and if it's not finished within the interval, you basically kill it - send the interruption to it.

Related

Daemon thread with infinite loop not terminating

I have a simple test program (garage simulation) with several threads (Vehicle, MysteryVehicle, Observer objects) instantiated and started. Only the Observer object is a daemon thread running an infinite loop.
After all non-daemon threads terminate, Observer thread never does and the loop is executed infinitely (so this isn't some buffered output after the daemon thread really terminates - it does go on forever).
All of the non-daemon threads print something to the console just before exiting their run() methods, and it clearly shows all of them really terminated. I also didn't call join() on the daemon thread. When printing out all currently running threads, observer is listed as well, so my guess is that this daemon thread isn't terminating properly.
The complete code can be found on this commit.
Below you can see all threads created, started and where exactly is join() called.
Main.java
package garage;
import java.util.Set;
import garage.model.*;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
Platform platform = new Platform();
Vehicle.platform = platform;
platform.print();
Vehicle[] vehicles = new Vehicle[30];
for (int i = 0; i < 30; i++) {
vehicles[i] = new Vehicle();
}
for (int i = 0; i < 30; i++) {
vehicles[i].start();
}
Observer observer = new Observer();
observer.platform = platform;
observer.start();
MysteryVehicle mysteryVehicle = new MysteryVehicle();
mysteryVehicle.start();
try {
mysteryVehicle.join();
} catch (Exception exception) {
exception.printStackTrace();
}
try {
for (int i = 0; i < 30; i++)
vehicles[i].join();
} catch (Exception exception) {
exception.printStackTrace();
}
System.out.println("before");
platform.print();
System.out.println("after");
synchronized (Platform.lock) {
System.out.println("END");
System.out.println(platform.flag); // checks whether wait() was called anytime
}
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread t : threads) {
System.out.println(t.getName());
}
}
public static void main(String[] args) {
launch(args);
}
}
Observer.java
package garage.model;
public class Observer extends Thread {
public Platform platform;
static int count = 0;
{
setName("observer");
setPriority(MIN_PRIORITY);
setDaemon(true);
}
#Override
public void run() {
while (true) {
synchronized (Platform.lock) {
try {
System.out.println(++count);
platform.print();
Platform.lock.wait(5000); // hack for when there is no meaningful loop condition
} catch (InterruptedException exception) {
exception.printStackTrace();
} finally {
Platform.lock.notifyAll();
}
}
}
}
}
Vehicle run() method - relevant part
public void run() {
...
System.out.println("done");
}
MysteryVehicle run() method - relevant part
public void run() {
synchronized (Platform.lock) {
System.out.println("And the vehicle disappears!");
...
}
}
All of the relevant thread messages are printed out to the console.
done - 30 times, And the vehicle disappears!, before, after, END, true
This is the list of all of the running threads:
Attach Listener
main
Common-Cleaner
JavaFX Application Thread
Signal Dispatcher
Finalizer
InvokeLaterDispatcher
Reference Handler
QuantumRenderer-0
observer
Thread-2
JavaFX-Launcher
Since the program doesn't terminate and the print() function the run() method of observer calls is executed infinitely, what is it that prevents the daemon thread from terminating?
What am I missing here?
I suspect main() never returns, so the main thread (and perhaps some of those FX threads) are still running.
From the Application doc:
The launch method does not return until the application has exited,
either via a call to Platform.exit or all of the application windows
have been closed.
The posted code has no window to close nor is Platform.exit() invoked.
As far as I know, calling join on daemon thread is a bad idea.The idea behind using daemon thread is it will not halt JVM from exiting. What you can do is send an interrupt to that thread and call join after that.

How to restart thread without using Thread.stop()?

I have a client-server application that runs the receive method to run in a separate thread. Thread is given some time to finish the job and the thread will be checked for the status.
There are occasions when the receive method will be blocked due to packet or ACK loss. If that happens, how can I stop the thread and start it again the next attempt?
As we all know, Thread.stop() is deprecated.
You can't restart a Java thread at all, with or without Thread.stop().
You have to create a new one.
You can however reuse a Runnable.
You can use interrupts to send to the thread and handle them to do a retry. Here is a sample that will start a thread that will not quit until the boolean done is set. However i'm interrupting the thread from a main thread to make it start over.
public class Runner implements Runnable {
private boolean done;
#Override
public void run() {
while (!done) {
try {
doSomeLongRunningStuff();
} catch (InterruptedException e) {
System.out.println("Interrupted..");
}
}
}
private void doSomeLongRunningStuff() throws InterruptedException {
System.out.println("Starting ... ");
Thread.sleep(300);
System.out.println("Still going ... ");
Thread.sleep(300);
done = true;
System.out.println("Done");
}
public static void main(final String[] args) throws InterruptedException {
final Thread t = new Thread(new Runner());
t.start();
Thread.sleep(500);
t.interrupt();
Thread.sleep(500);
t.interrupt();
}
}
Whether you can do it this way or not depends on what you are calling. Your framework doing the TCP connection may or may not support interrupting.
We should not restart a thread which is not valid , once thread has comepleted its execution.

Java MultiThreading Stop Method

What will happen if we access a thread which was stopped using stop() method.
UserThread t = new UserThread();
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
System.out.println(t.getState());
Anyhow stop() method is deprecated in java8, but need the output for above. Is it possible to access the thread which was stopped means in terminated state?
Thanks in advance.
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock
all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath exception propagates up the stack.) If any of the objects
previously protected by these monitors were in an inconsistent state,
other threads may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on damaged
objects, arbitrary behavior can result. This behavior may be subtle
and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the
user has no warning that his program may be corrupted. The corruption
can manifest itself at any time after the actual damage occurs, even
hours or days in the future.
What should I use instead of Thread.stop?
Most uses of stop should be replaced by code that simply modifies some
variable to indicate that the target thread should stop running. The
target thread should check this variable regularly, and return from
its run method in an orderly fashion if the variable indicates that it
is to stop running. To ensure prompt communication of the
stop-request, the variable must be volatile (or access to the variable
must be synchronized).
For example, suppose your applet contains the following start, stop and run methods:
private Thread blinker;
public void start() {
blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void run() {
while (true) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
You can avoid the use of Thread.stop by replacing the applet's stop and run methods with:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
If you are interested in seeing what is the state of a thread after you call stop you can suppress the deprecation warning by adding #SuppressWarnings("deprecation") before your test class definition.
For instance try the following code:
#SuppressWarnings("deprecation")
class test {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
}
};
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
try {
Thread.sleep(1000); // wait for stop to take effect
}catch(Exception e) {}
System.out.println(t.getState());
}
}
Spoiler alert: the status is TERMINATED
Its advised not use stop() method in Thread class since this is deprecated.
If you want to abort the thread execution use interrupt()
class IntThread extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("Didn't Interrupt me !!!");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}
public static void main(String args[]){
IntThread t1=new IntThread();
t1.start();
try{
t1.interrupt();
}catch(Exception e){System.out.println("Exception handled "+e);}
}
}
You can refer link for more details about interrupt.

Alternative method to kill thread

I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks

I was searching for stopping java thread gracefully and found that, but I cannot know how to check example of this situation

This is good example of stopping thread.
How to stop a java thread gracefully?
But when I try to check this example I received infinite loop.
This is my code:
public class Num {
public void crash(ManualStopping t1) {
t1.stopMe();
}
public static void main(String[] args) {
Num num = new Num();
ManualStopping t1 = new ManualStopping();
t1.run();
System.out.println("Main thread");
num.crash(t1);
}
}
class ManualStopping extends Thread {
volatile boolean finished = false;
public void stopMe() {
finished = true;
}
public void run() {
while (!finished) {
System.out.println("I'm alive");
}
}
}
I think you need to start your thread - not run it. By calling run, you are just making a normal method call, not running a separate thread.
Nothing in your code calls the stopMe method on ManualStopping. isInterrupted() is a test that doesn't change the state of the thread. And as #DaveHowes points out, you don't even start a separate thread.
t1.run(); Change it to t1.start().
Whats happening is that the thread you intend to spawn is not actually running as a separate thread. Instead the loop
while(!finished){ System.out.println("I'm alive"); }
is running on the main thread and your code num.crash(t1); never actually gets invoked. This is causing the infinite loop.

Categories

Resources