如何在Java中杀死Java .lang. thread ?


当前回答

这里有一些关于这个主题的好读物:

如何处理InterruptedException?

干净地关闭线程

其他回答

在用Java开发了15年之后,有一件事我想对世界说。

弃用Thread.stop()和所有反对其使用的神圣之战只是另一个坏习惯或设计缺陷不幸成为现实…(如。想谈谈Serializable接口吗?)

争论的焦点在于,杀死线程会使对象处于不一致的状态。所以呢?欢迎来到多线程编程。你是一个程序员,你需要知道你在做什么,是的。杀死线程会使对象处于不一致状态。如果你担心它使用一个标志,让线程优雅地退出;但有很多时候,我们没有理由担心。

但没有. .如果你输入thread.stop(),你很可能会被所有查看/注释/使用你代码的人杀死。所以你必须使用一个标志,调用interrupt(),在你的代码周围放置if(!标志),因为你根本没有循环,最后祈祷你用来进行外部调用的第三方库是正确编写的,并且没有不正确地处理InterruptException。

There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.

但是,这只是“体面的”,而不是绝对的,因为代码可以捕获ThreadDeath错误(或您显式抛出的任何异常),而不是像一个绅士线程应该做的那样重新抛出它。所以,AFAIA的底线是没有绝对的故障保险。

线程。停止是不赞成的,所以我们如何停止一个线程在Java ?

总是使用中断方法和未来请求取消

当任务响应中断信号时,例如阻塞队列采取方法。

Callable < String > callable = new Callable < String > () {
    @Override
    public String call() throws Exception {
        String result = "";
        try {
            //assume below take method is blocked as no work is produced.
            result = queue.take();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return result;
    }
};
Future future = executor.submit(callable);
try {
    String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    logger.error("Thread timedout!");
    return "";
} finally {
    //this will call interrupt on queue which will abort the operation.
    //if it completes before time out, it has no side effects
    future.cancel(true);
}

当任务不响应中断信号时。假设任务执行套接字I/O,不响应中断信号,因此使用上述方法将不会中止任务,future将超时,但取消finally块将没有影响,线程将继续侦听套接字。如果由pool实现,我们可以关闭套接字或在连接时调用close方法。

public interface CustomCallable < T > extends Callable < T > {
    void cancel();
    RunnableFuture < T > newTask();
}

public class CustomExecutorPool extends ThreadPoolExecutor {
    protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
        if (callable instanceof CancellableTask)
            return ((CancellableTask < T > ) callable).newTask();
        else
            return super.newTaskFor(callable);
    }
}

public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
    public synchronized void cancel() {
        try {
            obj.close();
        } catch (IOException e) {
            logger.error("io exception", e);
        }
    }

    public RunnableFuture < T > newTask() {
        return new FutureTask < T > (this) {
            public boolean cancel(boolean mayInterruptIfRunning) {
                try {
                    this.cancel();
                } finally {
                    return super.cancel(mayInterruptIfRunning);
                }
            }

        };
    }
}

我投票给Thread.stop()。

例如,您有一个持久的操作(如网络请求)。 假设您正在等待响应,但这可能需要时间,并且用户导航到其他UI。 这个等待线程现在是a)无用的b)潜在的问题,因为当他得到结果时,它是完全无用的,他将触发回调,从而导致大量错误。

所有这些,他可以做响应处理,这可能是CPU密集。作为开发人员,您甚至不能停止它,因为您不能在所有代码中抛出if (Thread.currentThread(). isinterrupted())行。

因此,无法强制停止线程是很奇怪的。

“杀死一个线程”不是一个正确的短语。这里有一种方法我们可以在will上实现线程的优雅完成/退出:

我使用的Runnable:

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

触发类:

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}