繁体   English   中英

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

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

我有一个帖子:

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();

让我们说没有客户端连接到服务器,所以这个线程将被阻止。现在我想杀死上面的线程t? 我怎么能杀了它?

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

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

我刚来到这个页面寻找相同的答案。 我找到了一种关闭线程的方法,这就是我要结束服务器的方法:

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();
}

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

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

你可以调用thread.interrupt() 这将在您的线程中抛出InterruptedException

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

为此Thread创建主线程MONITOR THREAD (从此产生这个新线程)join()。 如果在给定的超时后,此线程不“加入”,则可以忽略(nullify)此线程。 这将为您提供一个附加功能,为阻塞线程添加超时。

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

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();

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

我想你只需要关闭连接 - 所以简单地让scn成为线程的一个字段并实现:

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

并编写主要方法,以便在IOException或其他已完成的指示(正如您可能已经拥有)上正常退出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM