[英]How to stop thread without waiting client response
我有一個“ClientsHandler”class 讀取客戶端輸入並將其轉換為服務器命令。 問題是,當我在服務器控制台中使用 exit 命令時,runFlag 設置為 false,並且循環開始等待來自客戶端的最后一個輸入,然后再關閉線程。 如何在退出命令后立即中斷循環並停止線程?
class ClientsHandler(
private val socket: Socket,
private val commandManager: CommandManager
) : Runnable {
companion object {
var runFlag = true
fun close() {
runFlag = false
}
}
override fun run() {
var input = ObjectInputStream(socket.getInputStream())
var output = ObjectOutputStream(socket.getOutputStream())
var username = (input.readObject() as User).username
println("$username connected")
while (runFlag) {
try {
var request = input.readObject() as ServerRequest
output.writeObject(ServerCommandInvoker.invoke(request, commandManager))
} catch (e: Exception) {
println("$username disconnected")
runFlag = false
}
}
input.close()
output.close()
socket.close()
}
}
兩種選擇。
這是一個棘手的問題,因為 Java 庫規范明確保留對此不起作用的權利。 在大多數平台上它確實有效,但您可能應該跳過它,並為下面的第二個選項跳過 go。
這個想法是, theThreadThatIsCurrentlyBlockingOnTheReadObjectCall.interrupt()
通常會導致readObject()
調用立即退出並出現IOException
,其消息狀態類似於“線程中斷”。 您現在可以繼續。
不能保證這一點的原因是因為 java 需要在非常廣泛的平台和硬件上運行,也許並不是所有的平台和硬件都能做到這一點。
相反,從將runFlag
設置為false
的線程,您也可以直接關閉套接字。 這肯定會導致仍在運行的readObject()
調用立即退出,並帶有指示套接字現已關閉的IOException
。
請注意,您對runFlag
的設置對我來說似乎無效,因為它不使用volatile
或synchronized
或其他一些機制來確保此字段更新實際上可以從其他線程可靠地看到。 JVM 可以自由地使runFlag
更改對您的 ClientsHandler 運行方法可見,或者不可見 - JVM 的選擇。 因此,您甚至無法測試您的代碼是否損壞。
通常出於這樣的目的,您可以使用AtomicBoolean
,它保證一個線程中的寫入對另一個線程可見,而不會有很長的延遲。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.