Monitor Ctrl-Break 线程是啥
问题解决了,但是问题背后的问题,还没有得到解决:
Monitor Ctrl-Break 线程是啥?它是怎么来的?
我们先 jstack 一把看看线程堆栈呗。
而在 idea 里面,这里的“照相机”图标,就是 jstack 一样的功能。
我把程序恢复为最初的样子,然后把“照相机”就这么轻轻的一点:
从线程堆栈里面可以看到 Monitor Ctrl-Break 线程来自于这个地方:
com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
而这个地方,一看名称,是 idea 的源码了啊?
不属于我们的项目里面了,这咋个搞呢?
思考了一下,想到了一种可能,于是我决定用 jps 命令验证一下:
看到执行结果的时候我笑了,一切就说的通了。
果然,是用了 -javaagent 啊。
那么 javaagent 是什么?
好的,要问答好这个问题,就得另起一篇文章了,本文不讨论,先欠着。
只是简单的提一下。
你在命令行执行 java
命令,会输出一大串东西,其中就包含这个:
什么语言代理的,看不懂。
叫我们参阅 java.lang.instrument。
那它又是拿来干啥的?
简单的一句话解释就是:
使用 instrument 可以更加方便的使用字节码增强的技术,可以认为是一种 jvm 层面的截面。不需要对程序源代码进行任何侵入,就可以对其进行增强或者修改。总之,有点 AOP 内味。
而 -javaagent
命令后面需要紧跟一个 jar 包。
-javaagent:<jar 路径>[=<选项>]
instrument 机制要求,这个 jar 包必须有 MANIFEST.MF 文件,而 MANIFEST.MF 文件里面必须有 Premain-Class 这个东西。
所以,回到我们的程序中,看一下 javaagent 后面跟的包是什么。
在哪看呢?
就这个地方:
你把它点开,命令非常的长。但是我们关心的 -javaagent
就在最开始的地方:
此时此刻,我们距离真相,只有一步之遥了。
进到对应的包里,发现有三个 class 类:
我说过什么来着?
来,大声的跟我念一遍:源码之下无秘密。
Monitor Ctrl-Break 线程就是这里来的。
而仔细看一眼这里的代码,这个线程在干啥事呢?
Socket client = new Socket("127.0.0.1", portNumber);
啊,我的天呐,来看看这个可爱的小东西,socket 编程,太熟悉了,简直是梦回大学实验课的时候。
它是链接到 127.0.0.1 的某个端口上,然后 while(true) 死循环等待接收命令。
那么这个端口是哪个端口呢?
就是这里的 62325:
需要注意的是,这个端口并不是固定的,每次启动这个端口都会变化。
玩玩它
既然它是 Socket 编程,那么我就玩玩它呗。
先搞个程序:
public class SocketTest{
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("等待客户端连接.");
Socket socket = serverSocket.accept();
System.out.println("有客户端连接上了 "+ socket.getInetAddress() + ":" + socket.getPort() +"");
OutputStream outputStream = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
while (true)
{
System.out.println("请输入指令: ");
String s = scanner.nextLine();
String message = s + "\n";
outputStream.write(message.getBytes("US-ASCII"));
}
}
}
我们把服务端的端口指定为了 12345。
客户端这边的端口也得指定为 12345,那怎么指定呢?
别想复杂了,简单的一比。
把这行日志粘贴出来:
需要说明的是,我这边为了演示效果,在程序里面加了一个 for 循环。
然后我们在这里把端口改为 12345:
把文件保存为 start.bat 文件,随便放一个地方。
万事俱备。
我们先把服务端运行起来:
在 cmd 窗口里面输出了我们的日志,说明程序正常运行。
而在服务端这边,显示有客户端连接成功。
叫我们输入指令。
输入啥指令呢?
看一下客户端支持哪些指令呗:
可以看到,支持 STOP 命令。
接受到该命令后,会退出程序。
来,搞一波,动图走起:
搞定。
好了,本文技术部分就到这里了,恭喜你知道了 idea 中的 Monitor Ctrl-Break 线程,这个学了没啥卵用的知识 。
如果要深挖的话,往 -javaagent
方向挖一挖。
应用很多的,比如耳熟能详的 Java 诊断工具 Arthas 就是基于 JavaAgent 做的。
有点意思。
https://developer.aliyun.com/article/901820