taoeaten
taoeaten

Reputation: 37

How to kill a thread imported from third-party lib?

I import a third-party lib in my project, and now we publish it on Websphere(I use a ServletContextListener to clean all the treads in my application, use Thread.stop() method), but everytime we redeploy this app, I found the old thread still alive, I search on internet,and know it shoud use a voilate member or with interrupt(), but I don't wanna hack on third-party lib, so who can give me a hint?
thanks:)
third-party lib code as follow:

public void run() {
      while (true) {
            try {
                for (DefaultFuture future : FUTURES.values()) {
                    if (future == null || future.isDone()) {
                        continue;
                    }
                    if (System.currentTimeMillis() - future.getStartTimestamp() > future.getTimeout()) {
                        // create exception response.
                        Response timeoutResponse = new Response(future.getId());
                        // set timeout status.
                        timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT);
                        timeoutResponse.setErrorMessage(future.getTimeoutMessage(true));
                        // handle response.
                        DefaultFuture.received(future.getChannel(), timeoutResponse);
                    }
                }
                Thread.sleep(30);
            } catch (Throwable e) {
                logger.error("Exception when scan the timeout invocation of remoting.", e);
            }
        }
    }

I make a simple local test, and found thread.stop() can stop the thread, and use local jetty, I can reproduce the problem, who can explain it?


my local test code:

public class Test {
public static void main(String[] args) throws InterruptedException, IOException {
    myThread t1 = new myThread();
    t1.start();
    Thread.sleep(4000);
    t1.stop();
    System.in.read();
}

}

class myThread extends Thread{
@Override
public void run() {
    int i=0;
    while(true){
        try {
            System.out.println(i++);
            Thread.sleep(30);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

}

Upvotes: 0

Views: 198

Answers (1)

yushulx
yushulx

Reputation: 12160

The stop method is deprecated. It is unsafe. You should read the Oracle tutorial - Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

Refer to the paragraph:

What should I use instead of Thread.stop? 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();
    }
}

Why don't you extend the third-party Class, and re-write the thread method?

Upvotes: 1

Related Questions