how to kill a thread which is waiting for blocking function call in Java?
Asked Answered
B

7

16

I have a thread:

Thread t = new Thread(){
    public void run(){
        ServerSocketConnection scn = (ServerSocketConnection)
                Connector.open("socket://:1234");
        // Wait for a connection.
        SocketConnection sc = (SocketConnection) scn.acceptAndOpen();
       //do other operation
    }
};
t.start();

Lets say no client is connecting to the Server, so this thread will be blocked.Now I want to kill the above thread t? How can I kill it?

Blackett answered 6/8, 2010 at 6:40 Comment(0)
G
12

Thread.interrupt() will not interrupt a thread blocked on a socket. You can try to call Thread.stop() or Thread.destroy(), but these methods are deprecated (edit: actually, absent in J2ME) and in some cases non-functional, for reasons you can read about here. As that article mentions, the best solution in your case is to close the socket that you're blocking on:

In some cases, you can use application specific tricks. For example, if a thread is waiting on a known socket, you can close the socket to cause the thread to return immediately. Unfortunately, there really isn't any technique that works in general. It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt, it wouldn't respond to Thread.stop either. Such cases include deliberate denial-of-service attacks, and I/O operations for which thread.stop and thread.interrupt do not work properly.

Gilroy answered 6/8, 2010 at 6:57 Comment(3)
Are you sure? In which api are you looking? I can't find Thread.stop() in CLDC or MIDP...Cryptonymous
@aioobe: J2SE... in any case I'm saying don't use stop()Gilroy
I think the main point is still relevant: you have to kill what you're blocking on, you can't just kill the thread directly... I'm guessing the reason stop() doesn't exist in J2ME is because of the reasons given in the article I linked.Gilroy
C
0

You can call thread.interrupt(). This will throw a InterruptedException in your thread

Countercurrent answered 6/8, 2010 at 6:49 Comment(3)
are you sure? acceptAndOpen is not declared to throw InterruptedExceptionCryptonymous
this is a runtime Exception that's not generated by acceptAndOpen but by the Thread-class.Countercurrent
In which API is InterruptedException a runtime exception? You have an URL?Cryptonymous
D
0

Call Thread.interrupt(). Blocking operations typically throw an InterruptedException if the Thread they are executing on is interrupted.

Deliberate answered 6/8, 2010 at 6:50 Comment(0)
H
0

Make the main Thread MONITOR THREAD (from where you spawn this new Thread) join() for this Thread. If after a given time-out, this thread does not "join" then you can ignore (nullify) this thread. This will give you an added functionality adding time-out for blocking thread.

Hydrozoan answered 6/8, 2010 at 6:53 Comment(0)
C
0

In your main thread (when you want to terminate the accept-thread) call scn.close(). The acceptAndOpen should then throw an IOException, which you may catch and then terminate the accept-thread gracefully.

ServerSocketConnection scn =
    (ServerSocketConnection) Connector.open("socket://:1234");

Thread t = new Thread(){
    public void run(){
        // Wait for a connection.
        try {
            SocketConnection sc = (SocketConnection) scn.acceptAndOpen();
            //do other operation
        } catch (IOException e) {
            // Log the exception
        }
    }
};

t.start();

// ...

// Somewhere else...
// Cancel the acceptAndOpen.
scn.close();

A good idea would be to introduce a synchronization mechanism so you don't close the socket right after the acceptAndOpen went through.

Cryptonymous answered 6/8, 2010 at 6:57 Comment(0)
B
0

I think you would just need to close the connection - so simply make scn a field of the thread and implement:

public void stop() {
  scn.close();
}

and code your main method to exit gracefully on IOException or other indication that you are done (as you probably already have).

Billmyre answered 6/8, 2010 at 7:1 Comment(0)
V
0

I just came to this page looking for the same answer. I found a way to close Threads and this is what I do to end the server:

private Thread serverThread;

public void setUp(){
    //Run the server
    serverThread = new Thread() {
        public void run() {
            try {
                new Server(); //it calls acceptAndOpen() here
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    };
    serverThread.start();
}

public void tearDown() {
    serverThread = null;
    System.gc();
}

Basically, make your reference to your server thread null, and then let the garbage collector clean up resources (which is your server) for you.

Note though: This is far from perfect, we should never depend on gc to do its job, but it seems to work everytime I've tried it

Villose answered 23/11, 2012 at 0:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.