【问题标题】:Are Java threads created in user space or kernel space?Java 线程是在用户空间还是内核空间中创建的?
【发布时间】:2013-08-19 03:52:55
【问题描述】:

检查此代码

    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() 
        {
            try
            {
                System.out.println("STARTING SERVER...");
                ServerSocket s = new ServerSocket(2544);
                System.out.println("SERVER BLOCKED ON ACCEPT");
                Socket ss = s.accept();
                System.out.println("SERVER NOT BLOCKED ANYMORE");
            }
            catch(Exception ex)
            {
                ex.printStackTrace();
            }
        }
    });
    t1.start();



    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() 
        {
            try
            {
                while(true)
                {
                    Thread.sleep(1000);
                    System.out.println("Hello");
                }
            }
            catch(Exception ex)
            {
                ex.printStackTrace();
            }
        }
    });
    t2.start();

输出:

STARTING SERVER...
SERVER BLOCKED ON ACCEPT
Hello
Hello
Hello
Hello
Hello
Hello
Hello
...

Java 线程应该是用户空间线程,对吧?所以一个被阻塞的线程应该阻塞整个过程......那不是发生的事情。他们怎么了?

【问题讨论】:

  • 如果一个被阻塞的线程阻塞了整个进程,多线程的意义何在?
  • 用户空间线程消耗更少的资源,因为它们不必加载内核线程的程序计数器、堆栈等
  • @fredcrs 是的,但它们实际上并不能很好地工作。
  • 当两个主题都 100% 占用 CPU 时,它们可能会很有用。所以内核不会花时间切换上下文
  • 上下文切换开销仅在极少数情况下才会变得明显 - 准备就绪的线程比内核多,并且这些线程使用的数据太多以至于需要刷新大部分 L1 缓存。并不是所有的应用都是这样的。

标签: java multithreading kernel


【解决方案1】:

Java 线程是“用户”线程,但在底层,Java 虚拟机使用内核线程并在其内核线程池中的每个内核线程上委派用户线程 CPU 时间。请参阅this question 以获得更好的解释。似乎线程是特定于 JVM 供应商的,我的理解可能并不适用于所有 JVM 实现。

【讨论】:

    【解决方案2】:

    大多数 JVM 使用本机操作系统级线程实现线程,包括基于 OpenJDK 的 Oracle 参考实现。

    我想使用“绿色线程”(线程的用户空间模拟)的 JVM 会使用抢占式调度,这样一个线程中的无限循环就不会阻塞其他线程,但是在不了解特定实现的情况下,这只是猜测。

    【讨论】:

      【解决方案3】:

      Java 线程肯定是用户线程,但最终它们会在真正执行之前映射到内核级线程。这种映射可能取决于特定的 JVM 实现(或 the mapping model)。

      调度方面,内核线程在操作系统级别由一个定期中断内核的闹钟来调度。 IMO,当这种情况发生时,您的 JVM 线程(可能是多个)可能会执行它的代码,或者可能会产生另一个线程(这可能导致操作系统创建另一个内核线程或根据映射模型阻止它),或者可能运行它自己的特定调度算法来决定哪个线程之前被同一个锁阻塞,接下来将进行上下文切换等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        • 2014-09-10
        • 1970-01-01
        • 2012-11-03
        • 2020-12-04
        • 2012-01-17
        • 2018-03-27
        相关资源
        最近更新 更多