System.out.println如何在线程级别工作?



我正在调查在一个简单的HelloWorldjava程序上进行了哪些系统调用。使用简单的strace,我注意到没有write呼叫,我发现可疑:

...
mprotect(0x7f0bcd852000, 4096, PROT_READ) = 0
mprotect(0x7f0bce915000, 790528, PROT_READ) = 0
getpid()                                = 27931
munmap(0x7f0bcf6ac000, 174284)          = 0
getpid()                                = 27931
mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f0bcf5d6000
clone(child_stack=0x7f0bcf6d5fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f0bcf6d69d0, tls=0x7f0bcf6d6700, child_tidptr=0x7f0bcf6d69d0) = 27932
futex(0x7f0bcf6d69d0, FUTEX_WAIT, 27932, NULLHello, World
) = 0
munmap(0x7f0bbfa6c000, 140063364)       = 0
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

因此,正如您在上面看到的,对于一个正常的strace调用,只进行了一个futex调用,它正在等待字符串地址。

所以,我用-f参数运行strace来查看所有线程:
[pid 28249] pread64(3, "312376272276009330n2374f56123java/n"..., 6104, 4355323) = 6104
[pid 28249] pread64(3, "312376272276009306n2374f56120java/l"..., 4455, 3263638) = 4455
[pid 28249] write(1, "Hello, Worldn", 13Hello, World
) = 13
[pid 28249] pread64(3, "312376272276009(n2374f56125java/l"..., 999, 4425942) = 999
[pid 28249] mmap(0x7f9d35ae2000, 16384, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f9d35ae2000
[pid 28249] mprotect(0x7f9d2c2e7000, 8192, PROT_READ|PROT_WRITE) = 0

像这样,我可以看到write调用以及更多的futex调用。

我的问题是,当System.out.println被调用时,在线程级别究竟发生了什么?Java是否创建一个专用的线程用于打印,然后与主线程同步?此外,他们使用什么来进行同步,最终使futex调用。

System.out.println与线程无关(除了PrintStream方法是同步的,但在非争用情况下这无关紧要)。

Java启动器在新线程中创建JVM,这就是为什么任何Java代码(不仅仅是println)都在非原始线程中执行。

在原始线程中运行Java代码会导致许多问题,详细信息请参见JDK-6316197。

Java的System.out是一个PrintStream,它的一个方法是:

public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}

可以看到同步(就像该类中所有其他print方法一样)。

使用是为了在多个线程写入系统时不会得到乱码。out(或任何其他PrintStream)。至少它更容易控制全字符串参数,而不是编写单个字符。这也是可能的,但可能会导致输出乱码。

我不知道其余的,如何处理操作系统依赖的I/O的内部工作,可能还有更多的事情要做。但是我没有看。

相关内容

  • 没有找到相关文章

最新更新