java - 如何终止套接字连接上的线程阻塞

标签 java android multithreading sockets

在我的 Android 应用程序中,我的 Activity 正在为某些套接字网络操作启动另一个线程,并且该线程始终等待来自套接字的传入数据(阻塞 read() 函数中的 >while 循环)。

现在,当我的 Activity 被破坏时,我想保持事物干净,并销毁该线程。为了实现此功能,我定义了一个 volatile boolean 变量isSupposeToStop,它将初始化为false,并且当onStop()时code> 被调用,它将 boolean 设置为 true,并调用 socket.shutdownInput() 这会导致线程在 read 上阻塞() 抛出 IOException,然后读取 isSupposedToStop boolean 值以了解它应该停止。(如果您有更好的方法欢迎大家讨论)。

因此,在连接套接字后的 run() 实现中,我有:

sock= new Socket("127.0.0.1", 1234);
InputStream is= sock.getInputStream();
byte[] buffer= new byte[200];
while(true){
    if(isSupposedToStop) return;
    try {
        is.read(msgSizeBuff, 0, 200);
    } catch(IOException e){
    }
    if(isSupposedToStop) return;
    //do something with the received message
}

onStop()中,我有:

isSupposedToStop= true;
if(sock!= null) {
    try {
        sock.shutdownInput();
        sock.close();
    } catch (IOException e) {
    }
}
thread.join()

效果很好。当线程等待新数据时(在 read() 上阻塞),read()onStop 时立即抛出 IOException () 调用 shutdownInput(),控制权返回到读取我的 boolean 值并退出的线程。 但是如果在线程仍在等待建立连接时调用 onStop() (在 new Socket() 上阻塞),那么如果主机停机一段时间,就会出现问题例如,应用程序卡住了大约 3 秒,那么您是否建议忽略 thread.join() 调用?或者有没有办法唤醒这个线程?

最佳答案

一旦你调用了read方法,你基本上就被阻塞了——你只能通过中断线程来逃脱。

public void test() {
    Thread socketThread = new Thread(new Runnable() {

        @Override
        public void run() {
            System.out.println("Hello");
        }
    });
    // Do your stuff.
    //...
    // Time to quit - should abort any blocked reads.
    socketThread.interrupt();
}

另一种选择 - 这可能根本不起作用 - 是使用 InputStreamavailable 方法。

public void test() throws IOException {
    Socket sock = new Socket("127.0.0.1", 1234);
    InputStream is = sock.getInputStream();
    boolean done = false;
    while (!done) {
        int available;
        if ((available = is.available()) > 0) {
            // Your read stuff.
            is.read(buffer, 0, available);
        }
    }
}

关于java - 如何终止套接字连接上的线程阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35019783/

相关文章:

java - 为 Android 项目选择 ORM(最低 API 级别 7)

java - Android 上下文菜单项文本未显示

java - 在java中实例化递归定义的复合泛型类

android - 构建一个将连接到包含 SQL 数据库的服务器的 Android 应用程序。我应该怎么做?

php - 将 Web 应用程序转变为移动应用程序...PhoneGap?

java - 如何实现一个可以依次执行或随时停止的作业列表?

java - Wildfly 9 中的部署顺序

android - 检测与android map 中选定路线的偏差

c++ - 使用 GCC 和 OMP 在 C 中的特定线程顺序

java - 仅在添加到 HashSet 时同步是线程安全的吗?