在我的 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();
}
另一种选择 - 这可能根本不起作用 - 是使用 InputStream
的 available
方法。
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/