如何杀死一个正在等待 Java 中阻塞函数调用的线程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3421531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:46:00  来源:igfitidea点击:

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

javamultithreadingjava-memidp

提问by anupsth

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?

假设没有客户端连接到服务器,所以这个线程将被阻塞。现在我想杀死上面的线程 t?我怎样才能杀死它?

采纳答案by Tom Crockett

Thread.interrupt()will notinterrupt a thread blocked on a socket. You can try to call Thread.stop()or Thread.destroy(), but these methods are deprecated (edit: actually, absentin 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:

Thread.interrupt()不会中断受阻的插座上的线程。您可以尝试调用Thread.stop()Thread.destroy(),但这些方法已被弃用(编辑:实际上,J2ME 中不存在)并且在某些情况下无法正常工作,原因您可以在这里阅读。正如那篇文章所提到的,在您的情况下,最好的解决方案是关闭您阻塞的套接字:

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.

在某些情况下,您可以使用特定于应用程序的技巧。例如,如果一个线程正在等待一个已知的套接字,您可以关闭该套接字使该线程立即返回。不幸的是,真的没有任何技术可以通用。需要注意的是,在等待线程不响应 Thread.interrupt 的所有情况下,它也不会响应 Thread.stop。此类情况包括故意拒绝服务攻击,以及 thread.stop 和 thread.interrupt 无法正常工作的 I/O 操作。

回答by aioobe

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

在您的主线程中(当您想终止接受线程时)调用scn.close(). 然后acceptAndOpen应该抛出一个IOException,您可以捕获它,然后优雅地终止接受线程。

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 mechanismso you don't close the socket right after the acceptAndOpen went through.

一个好主意是引入同步机制,这样您就不会在 acceptAndOpen 完成后立即关闭套接字。

回答by Sam Brightman

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

我认为你只需要关闭连接 - 所以只需创建scn一个线程字段并实现:

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

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

并编写您的主要方法以优雅退出IOException或其他指示您已完成(您可能已经拥有)。

回答by Molten Ice

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.

基本上,将您对服务器线程的引用设为 null,然后让垃圾收集器为您清理资源(即您的服务器)。

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

但请注意:这远非完美,我们永远不应该依赖 gc 来完成它的工作,但它似乎每次我尝试过都有效

回答by Nikolaus Gradwohl

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

你可以打电话thread.interrupt()。这会InterruptedException在你的线程中抛出一个

回答by Tim Bender

Call Thread.interrupt(). Blocking operations typically throw an InterruptedExceptionif the Threadthey are executing on is interrupted.

调用Thread.interrupt()。如果正在执行的线程中断,阻塞操作通常会抛出InterruptedException

回答by Tushar Tarkas

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.

为这个线程创建主线程监视器线程(从你产生这个新线程的地方)join()。如果在给定的超时后,该线程没有“加入”,那么您可以忽略(无效)该线程。这将为您提供一个附加功能,为阻塞线程添加超时。