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

标签 java multithreading jvm java-threads

我正在研究在一个简单的 HelloWorld java 程序上进行了哪些系统调用。通过一个简单的 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, "\312\376\272\276\0\0\0009\0\330\n\0\2\0\3\7\0\4\f\0\5\0\6\1\0\23java/n"..., 6104, 4355323) = 6104
[pid 28249] pread64(3, "\312\376\272\276\0\0\0009\0\306\n\0\2\0\3\7\0\4\f\0\5\0\6\1\0\20java/l"..., 4455, 3263638) = 4455
[pid 28249] write(1, "Hello, World\n", 13Hello, World
) = 13
[pid 28249] pread64(3, "\312\376\272\276\0\0\0009\0(\n\0\2\0\3\7\0\4\f\0\5\0\6\1\0\25java/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.println 如何在线程级别工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68981436/

相关文章:

java - 我可以将类星体中的 SettableFuture 假设为光纤吗?

java - 获取所有 Antlr 解析错误作为字符串列表

scala - sbt 在 net.contentobjects.jnotify.macosx.JNotifyAdapterMacOSX.<init>(未知来源)上运行 ExceptionInInitializerError

java - 我们应该使用什么方法来代替 Hazelcast.getMap ("Map")?

java - JDBC 不将更新存储在 sqlite 数据库中

java - MongoDb 在其 java 驱动程序中的 $set 等效项

java - Java,数组,线程数,最小值,最大值

c# - 正确的投票方式?

java - 如何查看 JVM 内部(?)。我可以在工作应用程序中分析方法、参数、返回值等吗?

java - A星探路 |六角握把