Zbarcea Christian
Zbarcea Christian

Reputation: 9548

Java how to stop thread if the program was closed

I'm getting some exception and I need to know when the program closes itself because I need to close the socket.

I have the default public static main method where I'm keep repeating an action and a Thread class.

private static Thread thread;
public static boolean isRunning = true;  

public static void main(String[] args){

   thread = new Thread(new ThreadListenServer());
   thread.start();

   Timer timer = new Timer();
   TimerTask task = new TimerTask() {
      @Override
      public void run(){
         // some action
      }
   }

   timer.scheduleAtFixedRate(task, 0, 10000);

   isRunning = false;
}

And the thread class which is running in background:

public class ThreadListenServer implements Runnable{

    private DatagramSocket socket;

    public ThreadListenServer() throws SocketException{
       socket = new DatagramSocket(6655);
    }

    @Override
    public void run() {

       while(MainProgram.isRunning){
            // some action
       }

       socket.close();
    }
}

I don't know why, but isRunning it's becoming false, but it shouldn't. How am I supposed to close the socket if the main program was closed? (It's causing because the Thread still running in the background even if the program was closed).

I was thinking about to create the socket in the main class then I pass the socket object as a parameter to the ThreadClass and if the program is closed, than I should close the socket as well.

Upvotes: 4

Views: 6344

Answers (4)

MadProgrammer
MadProgrammer

Reputation: 347194

A few things come to mind.

  1. It would appear you are performing a blocking I/O operation using sockets. You may need to interrupt either the running thread and/or the socket to get it to stop blocking
  2. You should set the thread as daemon thread before it is started, using setDaemon(true). This will allow the JVM to terminate the thread automatically...
  3. isRunning should be marked volatile or you should use AtomicBoolean instead

Upvotes: 2

bluevoid
bluevoid

Reputation: 1349

Use:

thread.setDaemon(true);

This will shut the thread. It tells the JVM it is a background thread , so it will shut down on exit.

Upvotes: 4

goblinjuice
goblinjuice

Reputation: 3214

To stop all Threads when your program exits cleanly, you'll need to define a termination policy for each Thread that gets started. This is normally done using Interrupts and ExecutorService.shutdownNow() method sends an interrupt to each running thread.

A clean termination policy consists to two parts:

  • Sending stop signal to thread – aka interrupting it
  • Designing threads to act on interruption

A thread in Java could be interrupted by calling Thread.interrupt() method. Threads can check for interruption by calling Thread.isInterrupted() method. A good thread must check for interruption at regular intervals, e.g. as a loop condition and checking blocking functions for InterruptedExceptions.

It is important to note that Sockets in Java are oblivious to interruption. For example, if a Thread is blocked on Socket.accept(), it will not throw InterruptedException when the Thread is interrupted. In this case, you need to define a public method which closes the underlying socket by calling Socket.close() forcing the blocking function to throw an Exception (I guess SocketException).

Upvotes: 1

ug_
ug_

Reputation: 11440

Ill take the assumption you have a JFrame of some sort running as the class MainProgram. You have 2 options

1: set your Jframe to close all threads when it is closed.

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

2: add a window listener and manually close your thread (maybe you have to send some information across the socket before you close it)

addWindowListener(new WindowAdapter() {
  public void windowClosing(WindowEvent e) {
    // send your socket its close message and shut everything down
    System.exit(0);
  }
});

Upvotes: 2

Related Questions