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


当前回答

我没有得到中断工作在Android,所以我用这个方法,工作完美:

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }

其他回答

我投票给Thread.stop()。

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

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

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

试图突然终止线程是众所周知的糟糕编程实践,也是糟糕应用程序设计的证据。多线程应用程序中的所有线程显式或隐式地共享相同的进程状态,并被迫相互协作以保持一致,否则您的应用程序将容易出现很难诊断的错误。因此,开发人员有责任通过仔细和清晰的应用程序设计来保证这种一致性。

对于受控线程终止,有两种主要的正确解决方案:

使用共享volatile标志 使用Thread.interrupt()和Thread.interrupted()方法。

关于突发线程终止相关问题的详细解释,以及受控线程终止的错误和正确解决方案的示例,可以在这里找到:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

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

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

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

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

一般来说你不会…

你可以使用Thread.interrupt() (javadoc link)命令它中断正在做的事情。

在javadoc中有一个很好的解释(java technote链接)

线程。停止是不赞成的,所以我们如何停止一个线程在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);
                }
            }

        };
    }
}