亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

關于Socket read掛起的一些疑問?

關于Socket read掛起的一些疑問?

元芳怎么了 2019-01-30 18:34:07
有這么一個線程類(extends Thread)run方法中有如下代碼 while(true) { Socket socket = null; GZIPInputStream gzis = null; ObjectInputStream ois = null; try { socket = new Socket(IP, PORT); gzis = new GZIPInputStream(socket.getInputStream()); ois = new ObjectInputStream(gzis); Map<Integer, Object> result = (Map<Integer, Object>) ois.readObject(); doSomeBuziness(result); } catch(Exception e) { log.error(...); } finally { // clean work here sleep(1000); } } 即線程啟動后 每隔1秒 從Socket服務端接收數據 然后對接收到的數據做些業務邏輯處理 突然發現數據好像一直沒有更新 通過jstack命令 可知該線程已經掛起了 "Thread-5" daemon prio=10 tid=0x00002b54800cd000 nid=0x691f runnable [0x00002b5433be7000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:152) at java.net.SocketInputStream.read(SocketInputStream.java:122) at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:238) at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158) at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:116) 問: 為什么線程都掛起了 還是 RUNNABLE 狀態呢? 不是BLOCKED狀態呢? 這種掛起的底層機制是什么? 如對應什么系統命令 和下面等待鎖釋放導致線程掛起的區別是什么(底層機制有什么不同) static synchronized void foo() { Thread.sleep(10*60*1000); } 如有一個加了同步塊的foo方法 兩個線程都去調用這個foo方法 其中一個會被阻塞 "pool-1-thread-2" prio=5 tid=0x00007f9ed00a5000 nid=0x5503 waiting for monitor entry [0x00007000079c7000] java.lang.Thread.State: BLOCKED (on object monitor) at com.demo.LockDemo.foo(LockDemo.java:24) - waiting to lock <0x00000007aae446d0> (a java.lang.Class for com.demo.LockDemo) at com.demo.LockDemo$1.run(LockDemo.java:15) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 針對Socket read的這種掛起 不想重啟應用 有什么辦法可以人工顯式結束這種掛起嗎? at java.net.SocketInputStream.socketRead0(Native Method) 如 通過命令行顯式殺死這個socket 這樣的話可以拋個異常被捕獲 然后休眠一秒 可以繼續往下走了 不會卡住不動了
查看完整描述

3 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

你應該好好JDK關于線程狀態的文檔java.lang.Thread.State

public enum State {
    /**
     * Thread state for a thread which has not yet started.
     */
    NEW,
    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */
    RUNNABLE,
    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     */
    BLOCKED,
    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,
    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,
    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     */
    TERMINATED;
}

RUNNABLE狀態指的是,線程正在JVM中運行,但是它們需要等待來自操作系統的資源,比如說CPU資源,這里當然是網絡資源,所以它本該就是RUNNABLE的。BLOCKED狀態,專門指的是線程正在等待內置鎖的過程。WAITING說明線程正在等待另一個線程的特定操作。

想要結束這種等待,要么給與線程所需要的網絡資源(這種控制不了),要么直接關閉Socket,或者調用interrupt方法(其實底層也是關閉Socket,可以看看interruptAPI文檔)。

查看完整回答
反對 回復 2019-03-01
?
哆啦的時光機

TA貢獻1779條經驗 獲得超6個贊

我覺得設置 socket 的超時時間比較合適, 如

socket = new Socket(IP, PORT);
socket.setSoTimeout(1000 * 60);  // 讀操作的超時時間為 60 秒

如此, 當 socket read 在超過 60秒沒有收到數據時, 將拋出 SocketException 異常.

另外, 在 try finally 中應釋放資源(關閉 socket).

查看完整回答
反對 回復 2019-03-01
  • 3 回答
  • 0 關注
  • 742 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號