Java 个线程看起来是可运行的,即使它们是 waiting/blocked 个系统调用?
Do Java threads appear to be Runnable even if they are waiting/blocked on system call?
根据我的理解,进行 select/epoll/kqueue 系统调用会阻塞进行调用的线程或进程,直到套接字准备好进行 IO 或发生超时事件。在对基于 netty 的程序进行线程转储分析时,我看到父组线程在进行 select 调用后处于可运行状态,
"Parent Group1" #11 prio=5 os_prio=0 tid=0x000000001e575000 nid=0x3f98 runnable [0x000000001f2ce000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access0(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076bb59088> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x000000076b9706b8> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076b970308> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101)
at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:803)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:457)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at java.lang.Thread.run(Thread.java:745)
是否 Java 线程显示为 Runnable,即使它正在等待系统调用或者我遗漏了什么。
正如您从转储中看到的那样,是的。
Java 线程不是 "runnable" 仅当使用 Java 内置同步机制阻塞时,例如等待进入监视器(例如 Object.wait
、Thread.sleep
、Thread.join
)。
对 select
/epoll
/kqueue
和 JNI 的本机调用不会影响线程状态。
根据我的理解,进行 select/epoll/kqueue 系统调用会阻塞进行调用的线程或进程,直到套接字准备好进行 IO 或发生超时事件。在对基于 netty 的程序进行线程转储分析时,我看到父组线程在进行 select 调用后处于可运行状态,
"Parent Group1" #11 prio=5 os_prio=0 tid=0x000000001e575000 nid=0x3f98 runnable [0x000000001f2ce000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access0(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076bb59088> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x000000076b9706b8> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076b970308> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101)
at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:803)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:457)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at java.lang.Thread.run(Thread.java:745)
是否 Java 线程显示为 Runnable,即使它正在等待系统调用或者我遗漏了什么。
正如您从转储中看到的那样,是的。
Java 线程不是 "runnable" 仅当使用 Java 内置同步机制阻塞时,例如等待进入监视器(例如 Object.wait
、Thread.sleep
、Thread.join
)。
对 select
/epoll
/kqueue
和 JNI 的本机调用不会影响线程状态。