Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrupt/stop thread with socket I/O blocking operation

At some point of my server application I want to stop some threads that are performing I/O blocking operations.

For instance, one of them have the following run() method:

public void run() {
    System.out.println("GWsocket thread running");

    int len;
    byte [] buffer = new byte[1500];
    try {
        this.in  = new DataInputStream(this.socket.getInputStream());
        this.out = new DataOutputStream(this.socket.getOutputStream());
        running = true;

        while (running){
            len = in.read (buffer);
            if (len < 0)
                running = false;
            else
                parsepacket (buffer, len);
        }

    }catch (IOException ex) {
        System.out.println("GWsocket catch IOException: "+ex);
    }finally{
        try {
            System.out.println("Closing GWsocket");
            fireSocketClosure();
            in.close();
            out.close();
            socket.close();
        }catch (IOException ex) {
            System.out.println("GWsocket finally IOException: "+ex);
        }
    }
}

If I Want to stop a thread running this code, what should I do?

Here they show how to do (How do I stop a thread that waits for long periods (e.g., for input)?), but I don't understand what they mean with:

For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation: Thread.currentThread().interrupt();

Can anyone give me some hints? Some code examples would be very appreciated.

like image 415
amp Avatar asked Sep 07 '12 09:09

amp


People also ask

Does interrupt stop a thread?

interrupt() method: If any thread is in sleeping or waiting for a state then using the interrupt() method, we can interrupt the execution of that thread by showing InterruptedException. A thread that is in the sleeping or waiting state can be interrupted with the help of the interrupt() method of Thread class.

What is thread blocking?

A Blocked state will occur whenever a thread tries to acquire lock on object and some other thread is already holding the lock. Once other threads have left and its this thread chance, it moves to Runnable state after that it is eligible pick up work based on JVM threading mechanism and moves to run state.

Can a running thread be interrupted?

A thread can send an interrupt by invoking interrupt on the Thread object for the thread to be interrupted. This means interruption of a thread is caused by any other thread calling the interrupt() method.


2 Answers

A solution, described by Peter Lawrey and also seen here is to close the socket.

With nio, You could also use a SocketChannel which is interruptible and would allow the application of the standard interrupt model of Java.

A call to the interrupt method of your Thread object would throw an InterruptedException which would stop even your blocking IO operation.

like image 125
Denys Séguret Avatar answered Oct 26 '22 20:10

Denys Séguret


You can add a method like

public void close() throws IOException {
    this.socket.close();
}

and any blocking IO operations will throw a SocketException.

You might like to set a flag like closed which you can check if an exception thrown was to be expected or not.

BTW: You cannot be sure that you will get discrete packets on a read. It is far better to read what you need and use BufferedInputStream for efficiency. Only read blocks if you don't need to parse the contents e.g. copying from a socket to a file.

e.g. your read could get just one byte or get the end of one packet and the start of another.

like image 40
Peter Lawrey Avatar answered Oct 26 '22 21:10

Peter Lawrey