关于Socket read挂起的一些疑问?

有这么一个线程类(extendsThread)run方法中有如下代码
while(true){
Socketsocket=null;
GZIPInputStreamgzis=null;
ObjectInputStreamois=null;
try{
socket=newSocket(IP,PORT);
gzis=newGZIPInputStream(socket.getInputStream());
ois=newObjectInputStream(gzis);
Mapresult=(Map)ois.readObject();
doSomeBuziness(result);
}catch(Exceptione){
log.error(...);
}finally{
//cleanworkhere
sleep(1000);
}
}
即线程启动后每隔1秒从Socket服务端接收数据然后对接收到的数据做些业务逻辑处理
突然发现数据好像一直没有更新通过jstack命令可知该线程已经挂起了
"Thread-5"daemonprio=10tid=0x00002b54800cd000nid=0x691frunnable[0x00002b5433be7000]
java.lang.Thread.State:RUNNABLE
atjava.net.SocketInputStream.socketRead0(NativeMethod)
atjava.net.SocketInputStream.read(SocketInputStream.java:152)
atjava.net.SocketInputStream.read(SocketInputStream.java:122)
atjava.util.zip.InflaterInputStream.fill(InflaterInputStream.java:238)
atjava.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
atjava.util.zip.GZIPInputStream.read(GZIPInputStream.java:116)
问:
为什么线程都挂起了还是RUNNABLE状态呢?不是BLOCKED状态呢?
这种挂起的底层机制是什么?如对应什么系统命令和下面等待锁释放导致线程挂起的区别是什么(底层机制有什么不同)
staticsynchronizedvoidfoo(){
Thread.sleep(10*60*1000);
}
如有一个加了同步块的foo方法两个线程都去调用这个foo方法其中一个会被阻塞
"pool-1-thread-2"prio=5tid=0x00007f9ed00a5000nid=0x5503waitingformonitorentry[0x00007000079c7000]
java.lang.Thread.State:BLOCKED(onobjectmonitor)
atcom.demo.LockDemo.foo(LockDemo.java:24)
-waitingtolock<0x00000007aae446d0>(ajava.lang.Classforcom.demo.LockDemo)
atcom.demo.LockDemo$1.run(LockDemo.java:15)
atjava.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
针对Socketread的这种挂起不想重启应用有什么办法可以人工显式结束这种挂起吗?
atjava.net.SocketInputStream.socketRead0(NativeMethod)
如通过命令行显式杀死这个socket这样的话可以抛个异常被捕获然后休眠一秒可以继续往下走了不会卡住不动了
汪汪一只猫
浏览 607回答 2
2回答

慕桂英4014372

你应该好好JDK关于线程状态的文档java.lang.Thread.StatepublicenumState{/***Threadstateforathreadwhichhasnotyetstarted.*/NEW,/***Threadstateforarunnablethread.Athreadintherunnable*stateisexecutingintheJavavirtualmachinebutitmay*bewaitingforotherresourcesfromtheoperatingsystem*suchasprocessor.*/RUNNABLE,/***Threadstateforathreadblockedwaitingforamonitorlock.*Athreadintheblockedstateiswaitingforamonitorlock*toenterasynchronizedblock/methodor*reenterasynchronizedblock/methodaftercalling*{@linkObject#wait()Object.wait}.*/BLOCKED,/***Threadstateforawaitingthread.*Athreadisinthewaitingstateduetocallingoneofthe*followingmethods:**{@linkObject#wait()Object.wait}withnotimeout*{@link#join()Thread.join}withnotimeout*{@linkLockSupport#park()LockSupport.park}***Athreadinthewaitingstateiswaitingforanotherthreadto*performaparticularaction.**Forexample,athreadthathascalledObject.wait()*onanobjectiswaitingforanotherthreadtocall*Object.notify()orObject.notifyAll()on*thatobject.AthreadthathascalledThread.join()*iswaitingforaspecifiedthreadtoterminate.*/WAITING,/***Threadstateforawaitingthreadwithaspecifiedwaitingtime.*Athreadisinthetimedwaitingstateduetocallingoneof*thefollowingmethodswithaspecifiedpositivewaitingtime:**{@link#sleepThread.sleep}*{@linkObject#wait(long)Object.wait}withtimeout*{@link#join(long)Thread.join}withtimeout*{@linkLockSupport#parkNanosLockSupport.parkNanos}*{@linkLockSupport#parkUntilLockSupport.parkUntil}**/TIMED_WAITING,/***Threadstateforaterminatedthread.*Thethreadhascompletedexecution.*/TERMINATED;}RUNNABLE状态指的是,线程正在JVM中运行,但是它们需要等待来自操作系统的资源,比如说CPU资源,这里当然是网络资源,所以它本该就是RUNNABLE的。BLOCKED状态,专门指的是线程正在等待内置锁的过程。WAITING说明线程正在等待另一个线程的特定操作。想要结束这种等待,要么给与线程所需要的网络资源(这种控制不了),要么直接关闭Socket,或者调用interrupt方法(其实底层也是关闭Socket,可以看看interrupt的API文档)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript