用Java安全地中断线程

时间:2015-03-16 14:50:42

标签: java multithreading

在循环中有一个连接到服务器(HTTP)的线程并等待响应或响应超时(服务器在它有数据要返回之前不响应)。如果响应返回了一个处理它的线程。

在服务停止时,需要停止/中断所有线程,但线程必须完成响应处理(如果线程正在处理而不仅仅是等待响应)。

这是代码示例

public class WaitingResponseThread extends Thread {

    static final int TIMEOUT = 4 * 1000;
    static final int PROCESSING_DURATION = 2000;

    private volatile boolean stopped = false;
    private volatile boolean processing = false;

    public void run() {
        System.out.println("starting child thread");
        while(!stopped) {
            try {
                // here a thread is awaiting server response (in real life response timeout is 400 sec)
                // probably it is safe to interrupt the thread now
                // emulating this with Thread.sleep() 
                System.out.println("awaiting response");
                Thread.sleep(TIMEOUT);

                processing = true;

                // there is some job on response and we must allow it to finish the job
                // again emulating delay with Thread.sleep()
                Thread.sleep(PROCESSING_DURATION);

                processing = false;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("ending child thread");
    }

    public void setStopped(boolean stopped) {
        this.stopped = stopped;
    }

    public boolean isProcessing() {
        return processing;
    }

    public static void main(String[] args) {
        WaitingResponseThread t = new WaitingResponseThread();

        // starting thread, it sends a request and waits for a response
        t.start();

        try {
            Thread.sleep(1);

            // let's allow the thread to finish normally in case it is processing response
            t.setStopped(true);

            System.out.println("awaiting child thread to get response");
            Thread.sleep(TIMEOUT + 1);

            // let's allow the thread to finish processing
            while(t.isProcessing()) {
                System.out.println("processing");
                Thread.sleep(500);
            }

            // we can't wait for 400sec until the next loop check
            // so as the thread is sleeping we just interrupting it
            if(t.isAlive()) {
                System.out.println("killing");
                t.interrupt();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ending main thread");
    }
}

这种“中断”方法好吗?还有另一种方法是不等待超时并且不丢失正在处理的数据吗?

2 个答案:

答案 0 :(得分:0)

while(t.isProcessing()) {
    System.out.println("processing");
    Thread.sleep(500);
}

是一种民意调查。你应该不惜一切代价避免投票。如果可能,请使用一种委托形式,其中被调用者在完成处理时通知调用者。

除此之外,我非常确定打断一个帖子是你很少想做的事情,但如果你不得不这样做的话,你做这件事的方式也没问题。

答案 1 :(得分:0)

Thread类有一些在中断时可以使用的功能。

  • 抓取InterruptionException
  • 使用方法isInterrupted() (not static)
  • 使用方法interrupted() (static)
  • 检查interrupted()isInterrupted(),然后throw new InterruptedException()

有了这些,你可以让你的线程在杀死它之前完成当前的工作,可能在catch子句中。